ecoportal-api-graphql 1.3.16 → 2.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 (149) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +384 -6
  3. data/lib/ecoportal/api/common/graphql/model/diffable/leaf_diff_service.rb +97 -0
  4. data/lib/ecoportal/api/common/graphql/model/diffable.rb +1 -0
  5. data/lib/ecoportal/api/graphql/base/action.rb +1 -1
  6. data/lib/ecoportal/api/graphql/base/action_event.rb +23 -0
  7. data/lib/ecoportal/api/graphql/base/action_event_page.rb +16 -0
  8. data/lib/ecoportal/api/graphql/base/activity.rb +38 -0
  9. data/lib/ecoportal/api/graphql/base/activity_log.rb +38 -0
  10. data/lib/ecoportal/api/graphql/base/ai_summary_version.rb +12 -7
  11. data/lib/ecoportal/api/graphql/base/auth_log.rb +24 -0
  12. data/lib/ecoportal/api/graphql/base/authorization_result.rb +20 -0
  13. data/lib/ecoportal/api/graphql/base/contractor_entity/member_changes.rb +17 -5
  14. data/lib/ecoportal/api/graphql/base/file_container.rb +12 -4
  15. data/lib/ecoportal/api/graphql/base/location_classification_type.rb +2 -0
  16. data/lib/ecoportal/api/graphql/base/location_structure.rb +3 -0
  17. data/lib/ecoportal/api/graphql/base/minimal_dashboard.rb +25 -0
  18. data/lib/ecoportal/api/graphql/base/organization.rb +2 -0
  19. data/lib/ecoportal/api/graphql/base/page/data_field/contractor_entities.rb +26 -3
  20. data/lib/ecoportal/api/graphql/base/page/data_field/file_field.rb +47 -8
  21. data/lib/ecoportal/api/graphql/base/page/data_field/image_gallery.rb +5 -2
  22. data/lib/ecoportal/api/graphql/base/page/data_field/people.rb +50 -12
  23. data/lib/ecoportal/api/graphql/base/page/data_field.rb +12 -18
  24. data/lib/ecoportal/api/graphql/base/permissions.rb +15 -0
  25. data/lib/ecoportal/api/graphql/base/person_member_changelog.rb +23 -0
  26. data/lib/ecoportal/api/graphql/base/preset_view.rb +136 -1
  27. data/lib/ecoportal/api/graphql/base/register.rb +5 -0
  28. data/lib/ecoportal/api/graphql/base.rb +9 -0
  29. data/lib/ecoportal/api/graphql/builder/contractor_entity.rb +10 -0
  30. data/lib/ecoportal/api/graphql/builder/page.rb +0 -16
  31. data/lib/ecoportal/api/graphql/builder/template.rb +18 -0
  32. data/lib/ecoportal/api/graphql/compat/pages.rb +7 -2
  33. data/lib/ecoportal/api/graphql/compat/response.rb +14 -0
  34. data/lib/ecoportal/api/graphql/concerns/threadable.rb +58 -0
  35. data/lib/ecoportal/api/graphql/concerns.rb +1 -0
  36. data/lib/ecoportal/api/graphql/connection/action.rb +1 -1
  37. data/lib/ecoportal/api/graphql/connection/action_category.rb +1 -1
  38. data/lib/ecoportal/api/graphql/connection/activity.rb +11 -0
  39. data/lib/ecoportal/api/graphql/connection/activity_log.rb +11 -0
  40. data/lib/ecoportal/api/graphql/connection/auth_log.rb +11 -0
  41. data/lib/ecoportal/api/graphql/connection/contractor_entity.rb +1 -1
  42. data/lib/ecoportal/api/graphql/connection/minimal_dashboard.rb +11 -0
  43. data/lib/ecoportal/api/graphql/connection/page.rb +1 -1
  44. data/lib/ecoportal/api/graphql/connection/pages_workflow_command.rb +1 -1
  45. data/lib/ecoportal/api/graphql/connection/person_member.rb +1 -1
  46. data/lib/ecoportal/api/graphql/connection/person_member_changelog.rb +11 -0
  47. data/lib/ecoportal/api/graphql/connection/preview_page.rb +1 -1
  48. data/lib/ecoportal/api/graphql/connection.rb +5 -0
  49. data/lib/ecoportal/api/graphql/diff/pairing/signals.rb +21 -1
  50. data/lib/ecoportal/api/graphql/file_upload/client.rb +199 -140
  51. data/lib/ecoportal/api/graphql/fragment/activity.rb +84 -0
  52. data/lib/ecoportal/api/graphql/fragment/activity_log.rb +75 -0
  53. data/lib/ecoportal/api/graphql/fragment/auth_log.rb +29 -0
  54. data/lib/ecoportal/api/graphql/fragment/authorization_result.rb +14 -0
  55. data/lib/ecoportal/api/graphql/fragment/location_node.rb +1 -0
  56. data/lib/ecoportal/api/graphql/fragment/minimal_dashboard.rb +31 -0
  57. data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +21 -0
  58. data/lib/ecoportal/api/graphql/fragment/permissions.rb +98 -0
  59. data/lib/ecoportal/api/graphql/fragment/person_member_changelog.rb +33 -0
  60. data/lib/ecoportal/api/graphql/fragment.rb +7 -0
  61. data/lib/ecoportal/api/graphql/input/action/update.rb +12 -0
  62. data/lib/ecoportal/api/graphql/input/contractor_entity/manager_settings.rb +20 -0
  63. data/lib/ecoportal/api/graphql/input/contractor_entity/update.rb +6 -27
  64. data/lib/ecoportal/api/graphql/input/contractor_entity.rb +1 -0
  65. data/lib/ecoportal/api/graphql/input/date_range.rb +16 -0
  66. data/lib/ecoportal/api/graphql/input/location_structure/apply_commands.rb +2 -2
  67. data/lib/ecoportal/api/graphql/input/location_structure/draft/add_commands.rb +2 -2
  68. data/lib/ecoportal/api/graphql/input/location_structure/update_command.rb +6 -2
  69. data/lib/ecoportal/api/graphql/input/preset_view/update.rb +16 -1
  70. data/lib/ecoportal/api/graphql/input/workflow_command/add_checklist_field_item.rb +19 -0
  71. data/lib/ecoportal/api/graphql/input/workflow_command/add_smart_fill_config.rb +23 -0
  72. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage.rb +3 -2
  73. data/lib/ecoportal/api/graphql/input/workflow_command/add_viewable_field.rb +45 -0
  74. data/lib/ecoportal/api/graphql/input/workflow_command/archive_public_config.rb +19 -0
  75. data/lib/ecoportal/api/graphql/input/workflow_command/create_public_config.rb +19 -0
  76. data/lib/ecoportal/api/graphql/input/workflow_command/edit_checklist_field_item.rb +19 -0
  77. data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +12 -2
  78. data/lib/ecoportal/api/graphql/input/workflow_command/edit_public_config.rb +19 -0
  79. data/lib/ecoportal/api/graphql/input/workflow_command/edit_smart_fill_config.rb +21 -0
  80. data/lib/ecoportal/api/graphql/input/workflow_command/edit_template_advanced_settings.rb +19 -0
  81. data/lib/ecoportal/api/graphql/input/workflow_command/edit_template_basic_settings.rb +27 -0
  82. data/lib/ecoportal/api/graphql/input/workflow_command/edit_template_container_uid.rb +45 -0
  83. data/lib/ecoportal/api/graphql/input/workflow_command/{edit_page_creator_permissions.rb → edit_template_creator_permissions.rb} +3 -2
  84. data/lib/ecoportal/api/graphql/input/workflow_command/edit_template_descriptions.rb +19 -0
  85. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/action_list.rb +31 -0
  86. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +3 -1
  87. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/date.rb +15 -2
  88. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/file.rb +21 -0
  89. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/image_gallery.rb +3 -2
  90. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/people.rb +27 -3
  91. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/plain_text.rb +3 -2
  92. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/rich_text.rb +3 -2
  93. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/select.rb +3 -2
  94. data/lib/ecoportal/api/graphql/input/workflow_command/move_field.rb +3 -2
  95. data/lib/ecoportal/api/graphql/input/workflow_command/move_viewable_field.rb +33 -0
  96. data/lib/ecoportal/api/graphql/input/workflow_command/remove_checklist_field_item.rb +19 -0
  97. data/lib/ecoportal/api/graphql/input/workflow_command/remove_smart_fill_config.rb +19 -0
  98. data/lib/ecoportal/api/graphql/input/workflow_command/remove_viewable_field.rb +21 -0
  99. data/lib/ecoportal/api/graphql/input/workflow_command/reorder_forces.rb +3 -2
  100. data/lib/ecoportal/api/graphql/input/workflow_command/reorder_section.rb +3 -2
  101. data/lib/ecoportal/api/graphql/input/workflow_command.rb +43 -5
  102. data/lib/ecoportal/api/graphql/input.rb +1 -0
  103. data/lib/ecoportal/api/graphql/interface/base_page.rb +36 -3
  104. data/lib/ecoportal/api/graphql/interface/location_structure/command.rb +2 -1
  105. data/lib/ecoportal/api/graphql/logic/connection.rb +17 -0
  106. data/lib/ecoportal/api/graphql/logic/input.rb +127 -0
  107. data/lib/ecoportal/api/graphql/model/action_event.rb +14 -0
  108. data/lib/ecoportal/api/graphql/model/action_event_page.rb +10 -0
  109. data/lib/ecoportal/api/graphql/model/activity.rb +14 -0
  110. data/lib/ecoportal/api/graphql/model/activity_log.rb +31 -0
  111. data/lib/ecoportal/api/graphql/model/auth_log.rb +11 -0
  112. data/lib/ecoportal/api/graphql/model/authorization_result.rb +12 -0
  113. data/lib/ecoportal/api/graphql/model/minimal_dashboard.rb +14 -0
  114. data/lib/ecoportal/api/graphql/model/organization.rb +27 -0
  115. data/lib/ecoportal/api/graphql/model/permissions.rb +179 -0
  116. data/lib/ecoportal/api/graphql/model/person_member.rb +7 -0
  117. data/lib/ecoportal/api/graphql/model/person_member_changelog.rb +15 -0
  118. data/lib/ecoportal/api/graphql/model.rb +9 -0
  119. data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +20 -10
  120. data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +25 -10
  121. data/lib/ecoportal/api/graphql/mutation/contractor_entity/update_manager_settings.rb +37 -0
  122. data/lib/ecoportal/api/graphql/mutation/contractor_entity.rb +1 -0
  123. data/lib/ecoportal/api/graphql/mutation/file_container/upload.rb +78 -0
  124. data/lib/ecoportal/api/graphql/mutation/file_container.rb +15 -0
  125. data/lib/ecoportal/api/graphql/mutation/template/update_related_page.rb +79 -0
  126. data/lib/ecoportal/api/graphql/mutation/template.rb +1 -0
  127. data/lib/ecoportal/api/graphql/mutation.rb +1 -1
  128. data/lib/ecoportal/api/graphql/payload/contractor_entity/manager_settings.rb +20 -0
  129. data/lib/ecoportal/api/graphql/payload/contractor_entity.rb +1 -0
  130. data/lib/ecoportal/api/graphql/payload/template/update_related_page.rb +15 -0
  131. data/lib/ecoportal/api/graphql/payload/template.rb +1 -0
  132. data/lib/ecoportal/api/graphql/payload/upload.rb +12 -0
  133. data/lib/ecoportal/api/graphql/payload.rb +1 -0
  134. data/lib/ecoportal/api/graphql/query/activity_logs.rb +78 -0
  135. data/lib/ecoportal/api/graphql/query/auth_logs.rb +51 -0
  136. data/lib/ecoportal/api/graphql/query/dashboard_search.rb +57 -0
  137. data/lib/ecoportal/api/graphql/query/location_structure.rb +2 -0
  138. data/lib/ecoportal/api/graphql/query/location_structures.rb +2 -0
  139. data/lib/ecoportal/api/graphql/query/page.rb +6 -1
  140. data/lib/ecoportal/api/graphql/query/page_activities.rb +56 -0
  141. data/lib/ecoportal/api/graphql/query/permissions.rb +35 -0
  142. data/lib/ecoportal/api/graphql/query/person_member_changelogs.rb +53 -0
  143. data/lib/ecoportal/api/graphql/query.rb +6 -0
  144. data/lib/ecoportal/api/graphql_version.rb +1 -1
  145. metadata +73 -12
  146. data/lib/ecoportal/api/graphql/input/workflow_command/edit_page.rb +0 -28
  147. data/lib/ecoportal/api/graphql/mutation/smart_fill/generate.rb +0 -36
  148. data/lib/ecoportal/api/graphql/mutation/smart_fill/submit_feedback.rb +0 -40
  149. data/lib/ecoportal/api/graphql/mutation/smart_fill.rb +0 -13
@@ -5,6 +5,133 @@ module Ecoportal
5
5
  class Input < Logic::BaseModel
6
6
  passthrough :clientMutationId
7
7
 
8
+ # Declarative set-diff macro for id-list fields that the schema exposes as
9
+ # `IdDiffInput { additions: [ID!], removals: [ID!] }` on the *update* mutation.
10
+ #
11
+ # Mixed into any Input class (whether it inherits from {Logic::Input} or from a
12
+ # `Base::` data model) via `extend`. {Logic::Input} extends it for its own subclasses;
13
+ # data-model Input classes call `extend Logic::Input::IdDiffFields` explicitly.
14
+ #
15
+ # Usage:
16
+ # class Update < Base::ContractorEntity
17
+ # extend Logic::Input::IdDiffFields
18
+ # id_diff_fields :associatedPeopleIds, :leadContractorIds
19
+ # end
20
+ #
21
+ # It installs (or augments) a `from_model` that, for each declared field, computes the
22
+ # delta DIRECTLY from the READ model's `doc[key]` vs `original_doc[key]` arrays:
23
+ # additions = current - original
24
+ # removals = original - current
25
+ # A field is omitted when unchanged. The delta is computed directly (NOT via the
26
+ # cascaded DiffService) because these array fields are dropped from the flat diff and
27
+ # the read model is `root!` (so its doc/original_doc resolve without cascade side effects).
28
+ module IdDiffFields
29
+ # @return [Array<Symbol>] the fields declared for set-diff on this class.
30
+ def id_diff_fields_list
31
+ @id_diff_fields_list ||= []
32
+ end
33
+
34
+ # Declares the id-list fields that must be reshaped into IdDiff `{ additions:, removals: }`.
35
+ # @param fields [Array<Symbol>] field names (as they appear in the read model's doc).
36
+ # @return [void]
37
+ def id_diff_fields(*fields)
38
+ id_diff_fields_list.concat(fields.flatten.map(&:to_sym)).uniq!
39
+ end
40
+
41
+ # Computes the IdDiff-shaped deltas for the declared fields and merges them into +diff+.
42
+ # @param model [Common::GraphQL::Model] the subject (read) model.
43
+ # @param diff [Hash, nil] the base mutation input hash to augment (may be nil).
44
+ # @return [Hash, nil] +diff+ with per-field `{ additions:, removals: }` merged in,
45
+ # or the original value when nothing changed.
46
+ def merge_id_diffs(model, diff)
47
+ id_diff_fields_list.each do |field|
48
+ key = field.to_s
49
+ current = Array(model.doc[key])
50
+ original = Array(model.original_doc[key])
51
+ next if current == original
52
+
53
+ diff ||= {}
54
+ diff[:id] ||= model.id if model.respond_to?(:id)
55
+ diff[field] = { additions: current - original, removals: original - current }
56
+ end
57
+ diff
58
+ end
59
+
60
+ # Reshaping `from_model`: base diff (via {Logic::Input.from_model}) + set-diff deltas.
61
+ # @param model [Common::GraphQL::Model] the subject model.
62
+ # @return [Hash, nil] the mutation input hash, or nil when there are no changes.
63
+ def from_model(model, **kargs)
64
+ diff = Logic::Input.from_model(model, **kargs)
65
+ merge_id_diffs(model, diff)
66
+ end
67
+ end
68
+
69
+ # Declarative FULL-ARRAY macro for id-list fields that the schema exposes as a plain
70
+ # `[ID!]` on the *update* mutation (NOT `IdDiffInput`). The server expects the COMPLETE
71
+ # current array, replacing the stored value wholesale — there is no additions/removals
72
+ # delta shape. This is the counterpart to {IdDiffFields}.
73
+ #
74
+ # Mixed into any Input class via `extend`, exactly like {IdDiffFields}. Data-model Input
75
+ # classes call `extend Logic::Input::FullArrayFields` explicitly.
76
+ #
77
+ # Usage:
78
+ # class Update < Base::Action
79
+ # extend Logic::Input::FullArrayFields
80
+ # full_array_fields :assignedPersonMemberIds, :locationIds, :fileContainerIds
81
+ # end
82
+ #
83
+ # It installs (or augments) a `from_model` that, for each declared field, emits the FULL
84
+ # current array taken DIRECTLY from the READ model's `doc[key]` whenever it differs from
85
+ # `original_doc[key]`. A field is omitted when unchanged. The value is read directly (NOT
86
+ # via the cascaded DiffService) because these array fields are dropped from the flat diff
87
+ # and the read model is `root!`.
88
+ #
89
+ # Schema evidence (live introspection 20260605, UpdateActionInput):
90
+ # assignedPersonMemberIds : [ID!]
91
+ # locationIds : [ID!]
92
+ # fileContainerIds : [ID!]
93
+ # None are `IdDiffInput` — hence full-array, not delta.
94
+ module FullArrayFields
95
+ # @return [Array<Symbol>] the fields declared for full-array emission on this class.
96
+ def full_array_fields_list
97
+ @full_array_fields_list ||= []
98
+ end
99
+
100
+ # Declares the id-list fields that must be emitted as their COMPLETE current array.
101
+ # @param fields [Array<Symbol>] field names (as they appear in the read model's doc).
102
+ # @return [void]
103
+ def full_array_fields(*fields)
104
+ full_array_fields_list.concat(fields.flatten.map(&:to_sym)).uniq!
105
+ end
106
+
107
+ # Emits the full current array for each changed declared field and merges it into +diff+.
108
+ # @param model [Common::GraphQL::Model] the subject (read) model.
109
+ # @param diff [Hash, nil] the base mutation input hash to augment (may be nil).
110
+ # @return [Hash, nil] +diff+ with per-field full arrays merged in, or the original
111
+ # value when nothing changed.
112
+ def merge_full_arrays(model, diff)
113
+ full_array_fields_list.each do |field|
114
+ key = field.to_s
115
+ current = Array(model.doc[key])
116
+ original = Array(model.original_doc[key])
117
+ next if current == original
118
+
119
+ diff ||= {}
120
+ diff[:id] ||= model.id if model.respond_to?(:id)
121
+ diff[field] = current
122
+ end
123
+ diff
124
+ end
125
+
126
+ # Reshaping `from_model`: base diff (via {Logic::Input.from_model}) + full arrays.
127
+ # @param model [Common::GraphQL::Model] the subject model.
128
+ # @return [Hash, nil] the mutation input hash, or nil when there are no changes.
129
+ def from_model(model, **kargs)
130
+ diff = Logic::Input.from_model(model, **kargs)
131
+ merge_full_arrays(model, diff)
132
+ end
133
+ end
134
+
8
135
  class << self
9
136
  # Builds a mutation input hash from a model's diff.
10
137
  # Subclasses override this to reshape fields (e.g. array → IdDiffInput).
@@ -0,0 +1,14 @@
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Model
5
+ class ActionEvent < Base::ActionEvent
6
+ # assignedPersonMembers: [PreviewPersonMember!]! — Model::PersonMember's
7
+ # read fields are a compatible superset.
8
+ embeds_many :assignedPersonMembers, klass: Model::PersonMember
9
+ embeds_many :pages, klass: "Ecoportal::API::GraphQL::Model::ActionEventPage"
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Model
5
+ class ActionEventPage < Base::ActionEventPage
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Model
5
+ # Concrete read model for a page activity/history entry. Adds the
6
+ # relational embeds on top of the common interface fields in Base::Activity.
7
+ class Activity < Base::Activity
8
+ embeds_one :personMember, klass: Model::PersonMember, nullable: true
9
+ embeds_one :user, klass: Model::User, nullable: true
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Model
5
+ # Concrete read model for a System Access Log entry. Adds the relational
6
+ # embeds on top of the common union fields in Base::ActivityLog.
7
+ #
8
+ # `parentResource*` and `resource` are present only on the Dashboard* union
9
+ # members (DashboardAccess/Create/Delete/Update, DeniedDashboardAccess);
10
+ # they are nullable here so page/file/scim members resolve cleanly.
11
+ class ActivityLog < Base::ActivityLog
12
+ # Lightweight wrapper for the union members' `resource { isVisible }` selection.
13
+ # Defined before the embeds_one below that references it.
14
+ class Resource < Logic::BaseModel
15
+ read_only!
16
+
17
+ passthrough :__typename
18
+ embeds_one :isVisible, klass: Model::AuthorizationResult, nullable: true
19
+ end
20
+
21
+ passthrough :parentResourceId, :parentResourceName, :parentResourceType
22
+
23
+ embeds_one :user, klass: Model::User, nullable: true
24
+ # resource: only `isVisible: AuthorizationResult` is selected (the web
25
+ # feature's shape); the full Dashboard subtree is not modelled here.
26
+ embeds_one :resource, klass: Model::ActivityLog::Resource, nullable: true
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Model
5
+ class AuthLog < Base::AuthLog
6
+ embeds_one :targetUser, klass: Model::User
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Model
5
+ # Concrete model for a permission-check result. No extra wiring today; exists so
6
+ # `canXXX` fields embed `Model::AuthorizationResult` (and can grow a `reasons` model later).
7
+ class AuthorizationResult < Base::AuthorizationResult
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Model
5
+ class MinimalDashboard < Base::MinimalDashboard
6
+ # owner: MinimalUser (id/email/name) — modelled with the User model.
7
+ embeds_one :owner, klass: Model::User
8
+ # register: MinimalRegister — Model::Register's read fields are a compatible superset.
9
+ embeds_one :register, klass: Model::Register
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -7,6 +7,13 @@ module Ecoportal
7
7
  class Organization < Base::Organization
8
8
  DEFAULT_PATH = ['currentOrganization'].freeze
9
9
 
10
+ # permissions: Permissions! — the org-level canXXX ability set (~83 AuthorizationResult
11
+ # fields, e.g. dashboardCanManage, locationStructuresCanAiGenerateStructure,
12
+ # generatedPageFilterCanUseSmartQuery). Typed read when a fetched doc includes it;
13
+ # fetch natively via the `permissions` query below.
14
+ embeds_one :permissions,
15
+ klass: "Ecoportal::API::GraphQL::Model::Permissions", nullable: true
16
+
10
17
  class << self
11
18
  extend Ecoportal::API::Common::GraphQL::QueryIntegration
12
19
 
@@ -29,6 +36,26 @@ module Ecoportal
29
36
 
30
37
  query :contractorEntities,
31
38
  query_klass: 'Ecoportal::API::GraphQL::Query::ContractorEntities'
39
+ # System access logs (SCIM/security auditing) — AuthLogConnection
40
+ query :authLogs,
41
+ query_klass: 'Ecoportal::API::GraphQL::Query::AuthLogs'
42
+ # Org-level permission set (canXXX abilities) — Permissions
43
+ query :permissions,
44
+ query_klass: 'Ecoportal::API::GraphQL::Query::Permissions'
45
+ # System Access Logs feature — ActivityLogUnionConnection (rich filters:
46
+ # userIds/resourceIds/filterSuperusers/activityType/resourceType/source/dateFilter)
47
+ query :activityLogs,
48
+ query_klass: 'Ecoportal::API::GraphQL::Query::ActivityLogs'
49
+ # Page history / activity feed — ActivityInterfaceConnection.
50
+ # Resolves currentOrganization.page(id:).activities; pass `id:` (page id).
51
+ query :pageActivities,
52
+ query_klass: 'Ecoportal::API::GraphQL::Query::PageActivities'
53
+ # Person member changelog history — PersonMemberChangelogConnection
54
+ query :personMemberChangelogs,
55
+ query_klass: 'Ecoportal::API::GraphQL::Query::PersonMemberChangelogs'
56
+ # Dashboard search — MinimalDashboardConnection
57
+ query :dashboardSearch,
58
+ query_klass: 'Ecoportal::API::GraphQL::Query::DashboardSearch'
32
59
  #contractorEntity,
33
60
  query :actionCategories,
34
61
  query_klass: 'Ecoportal::API::GraphQL::Query::ActionCategories'
@@ -0,0 +1,179 @@
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Model
5
+ # Org-level permission set (Organization.permissions). Each `canXXX` field is an
6
+ # AuthorizationResult (`{ value message }`); all are non-null in the schema but modelled
7
+ # nullable so a partial selection (fetching only some canXXX) still reads cleanly.
8
+ class Permissions < Base::Permissions
9
+ embeds_one :actionCanCreateStandalone,
10
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
11
+ embeds_one :actionCanIndex,
12
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
13
+ embeds_one :alertNotificationCanAccessBroadcastNotifications,
14
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
15
+ embeds_one :alertNotificationCanCreate,
16
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
17
+ embeds_one :alertNotificationCanIndex,
18
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
19
+ embeds_one :canAccessAdminTools,
20
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
21
+ embeds_one :canAccessPeopleManager,
22
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
23
+ embeds_one :canDeleteActionCategories,
24
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
25
+ embeds_one :canIndex,
26
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
27
+ embeds_one :canListAttachablePersonMembers,
28
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
29
+ embeds_one :canManageActionCategories,
30
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
31
+ embeds_one :canManageStandaloneActionsPermissions,
32
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
33
+ embeds_one :canResetActionsCounter,
34
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
35
+ embeds_one :canUpload,
36
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
37
+ embeds_one :contractorEntityCanAccessContractorManager,
38
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
39
+ embeds_one :contractorEntityCanAttach,
40
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
41
+ embeds_one :contractorEntityCanCreate,
42
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
43
+ embeds_one :contractorEntityCanDestroy,
44
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
45
+ embeds_one :contractorEntityCanEdit,
46
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
47
+ embeds_one :contractorEntityCanEditLinkedUsers,
48
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
49
+ embeds_one :contractorEntityCanIndex,
50
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
51
+ embeds_one :contractorEntityCanManageParentContractors,
52
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
53
+ embeds_one :contractorEntityCanManageSubcontractors,
54
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
55
+ embeds_one :crossReferenceReportsCanIndex,
56
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
57
+ embeds_one :dashboardCanManage,
58
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
59
+ embeds_one :dataSetsCanIndex,
60
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
61
+ embeds_one :dataSpaceCanShow,
62
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
63
+ embeds_one :dataViewsCanIndex,
64
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
65
+ embeds_one :emailReportCanConfigureSmartReport,
66
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
67
+ embeds_one :filesCanIndex,
68
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
69
+ embeds_one :filesCanUpload,
70
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
71
+ embeds_one :generatedPageFilterCanCreate,
72
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
73
+ embeds_one :generatedPageFilterCanUseSmartQuery,
74
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
75
+ embeds_one :hasFileAbilityToDownload,
76
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
77
+ embeds_one :locationClassificationsCanCreate,
78
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
79
+ embeds_one :locationClassificationsCanUpdate,
80
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
81
+ embeds_one :locationStructuresCanAccess,
82
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
83
+ embeds_one :locationStructuresCanAdministrate,
84
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
85
+ embeds_one :locationStructuresCanAiGenerateStructure,
86
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
87
+ embeds_one :locationStructuresCanCreate,
88
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
89
+ embeds_one :locationStructuresCanManage,
90
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
91
+ embeds_one :locationStructuresCanManageSftpIntegration,
92
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
93
+ embeds_one :locationStructuresCanPublish,
94
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
95
+ embeds_one :locationStructuresCanRead,
96
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
97
+ embeds_one :locationStructuresCanScheduleUpdate,
98
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
99
+ embeds_one :locationStructuresCanUpdate,
100
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
101
+ embeds_one :organizationCanViewSettings,
102
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
103
+ embeds_one :pageAiSummaryCanAccess,
104
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
105
+ embeds_one :pageCanListDrafts,
106
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
107
+ embeds_one :pageCanRestore,
108
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
109
+ embeds_one :pageCanUseDrafts,
110
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
111
+ embeds_one :pageSmartAssistantCanChat,
112
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
113
+ embeds_one :personSchemaCanAccessManager,
114
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
115
+ embeds_one :publicTemplatesCanCopyLink,
116
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
117
+ embeds_one :publicTemplatesCanIndex,
118
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
119
+ embeds_one :publicTemplatesCanListEntries,
120
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
121
+ embeds_one :publicTemplatesCanManage,
122
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
123
+ embeds_one :registerAssistantCanChat,
124
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
125
+ embeds_one :registerCanAccessRegisterTools,
126
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
127
+ embeds_one :registerCanCreate,
128
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
129
+ embeds_one :registerCanLimitTemplates,
130
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
131
+ embeds_one :scimIntegrationCanAddCodeHooks,
132
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
133
+ embeds_one :scimIntegrationCanCreate,
134
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
135
+ embeds_one :scimIntegrationCanDestroy,
136
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
137
+ embeds_one :scimIntegrationCanGenerateApiKey,
138
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
139
+ embeds_one :scimIntegrationCanIndex,
140
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
141
+ embeds_one :scimIntegrationCanShow,
142
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
143
+ embeds_one :scimIntegrationCanShowLogs,
144
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
145
+ embeds_one :scimIntegrationCanUpdate,
146
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
147
+ embeds_one :spatialCanUpdateLocationNodeGeojson,
148
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
149
+ embeds_one :structuresCanIndex,
150
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
151
+ embeds_one :templateCanRestore,
152
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
153
+ embeds_one :userAccessLogsCanShow,
154
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
155
+ embeds_one :userCanAccessAdminArea,
156
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
157
+ embeds_one :userCanAccessPageCreationTools,
158
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
159
+ embeds_one :visitorLogCanAdminCheckIn,
160
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
161
+ embeds_one :visitorLogCanEdit,
162
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
163
+ embeds_one :visitorLogCanManage,
164
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
165
+ embeds_one :visitorLogCanShow,
166
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
167
+ embeds_one :visitorManagementCanAccessVisitorManager,
168
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
169
+ embeds_one :visitorManagementCanIndex,
170
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
171
+ embeds_one :webhooksCanManageSubscriptions,
172
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
173
+ embeds_one :webhooksCanViewSubscriptions,
174
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -6,6 +6,13 @@ module Ecoportal
6
6
  embeds_one :contractorOrganization, klass: "Ecoportal::API::GraphQL::Model::ContractorEntity"
7
7
  embeds_one :account, klass: Model::Account
8
8
 
9
+ # changelogs: [PersonMemberChangelog!] — audit history for this member.
10
+ embeds_many :changelogs, klass: "Ecoportal::API::GraphQL::Model::PersonMemberChangelog"
11
+
12
+ # canManageContractorAdmins: AuthorizationResult — permission check (nullable).
13
+ embeds_one :canManageContractorAdmins,
14
+ klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
15
+
9
16
  # embeds_many :privateFields, enum_class: Ecoportal::API::GraphQL::Model::MemberSchemaFields
10
17
  # embeds_many :publicFields, enum_class: Ecoportal::API::GraphQL::Model::MemberSchemaFields
11
18
  end
@@ -0,0 +1,15 @@
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Model
5
+ class PersonMemberChangelog < Base::PersonMemberChangelog
6
+ # `personMember` is a PreviewPersonMember (id/name/email) — modelled with the
7
+ # PersonMember model, whose read fields are a compatible superset.
8
+ embeds_one :personMember, klass: Model::PersonMember
9
+ # `user` is a MinimalUser (id/email/name) — modelled with the User model.
10
+ embeds_one :user, klass: Model::User
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -20,11 +20,20 @@ require_relative 'model/page_union'
20
20
  require_relative 'model/preview_page'
21
21
  require_relative 'model/resource'
22
22
  require_relative 'model/action'
23
+ require_relative 'model/action_event_page'
24
+ require_relative 'model/action_event'
23
25
  require_relative 'model/contractor_entity'
26
+ require_relative 'model/authorization_result'
27
+ require_relative 'model/permissions'
28
+ require_relative 'model/activity'
29
+ require_relative 'model/activity_log'
30
+ require_relative 'model/auth_log'
31
+ require_relative 'model/person_member_changelog'
24
32
  require_relative 'model/organization'
25
33
 
26
34
  require_relative 'model/register'
27
35
  require_relative 'model/preset_view'
36
+ require_relative 'model/minimal_dashboard'
28
37
 
29
38
  require_relative 'model/ai_summary_version'
30
39
  require_relative 'model/pages_workflow'
@@ -3,27 +3,38 @@
3
3
  class GraphQL
4
4
  module Mutation
5
5
  module AiSummary
6
- # Triggers AI summary generation for a page or stage.
7
- # Returns an AiSummaryVersion with the generated text and token usage.
8
- # Generation is synchronous — the response contains the result or an error.
6
+ # Triggers AI summary generation for a page or stage. Returns an `AiSummaryVersion`.
9
7
  #
10
- # stageId is optional: omit for page-level summary, provide for stage-level.
8
+ # Corrected 2026-07-30 against the live schema the previous wiring could never run:
9
+ # the mutation is `generatePageSummary(input: GenerateInput!)`, NOT `generateAiSummary`
10
+ # with flat `pageId`/`stageId` arguments, and `AiSummaryVersion` has no token fields.
11
+ #
12
+ # `stage_id` is optional: omit for a page-level summary, pass it for stage-level.
11
13
  class Generate < Logic::Mutation
12
- field_name :generateAiSummary
14
+ field_name :generatePageSummary
13
15
 
14
16
  class_resolver :payload_class, 'Ecoportal::API::GraphQL::Payload::AiSummaryGenerate'
15
17
 
18
+ def query(page_id:, stage_id: nil, **kargs, &block)
19
+ input = { pageId: page_id }
20
+ input[:stageId] = stage_id if stage_id
21
+ super(input: input, **kargs, &block)
22
+ end
23
+
16
24
  private
17
25
 
18
26
  def basic_block(&block)
19
27
  payload_block = block || default_payload_block
20
28
  proc {
21
- mutation(pageId: :id!, stageId: :id) {
22
- generateAiSummary(pageId: :pageId, stageId: :stageId, &payload_block)
29
+ mutation(input: :GenerateInput!) {
30
+ generatePageSummary(input: :input, &payload_block)
23
31
  }
24
32
  }
25
33
  end
26
34
 
35
+ # AiSummaryVersion exposes: aiSummary, alreadyRated, createdAt, dataFieldLogs,
36
+ # generationErrors, id, pagePatchVer, status. Only the plain scalars are selected —
37
+ # `dataFieldLogs` / `generationErrors` / `createdAt` need their own selections.
27
38
  def default_payload_block
28
39
  proc {
29
40
  errors { details fullMessages }
@@ -31,9 +42,8 @@
31
42
  id
32
43
  aiSummary
33
44
  status
34
- inputTokens
35
- outputTokens
36
- totalTokens
45
+ alreadyRated
46
+ pagePatchVer
37
47
  }
38
48
  }
39
49
  end
@@ -3,25 +3,40 @@
3
3
  class GraphQL
4
4
  module Mutation
5
5
  module AiSummary
6
- # Submit a thumbs-up / thumbs-down rating on an AI summary version.
7
- # sentiment: "THUMBS_UP" | "THUMBS_DOWN"
8
- # aiSummaryVersionId: returned from generateAiSummary.item.id
6
+ # Submit a rating on an AI summary version.
7
+ #
8
+ # Corrected 2026-07-30 against the live schema — the previous wiring could never run:
9
+ # the mutation is `submitPageAiSummaryFeedback(input: SubmitFeedbackInput!)`, the enum is
10
+ # `SentimentEnum` (there is no `AiSummarySentimentEnum`), and its values are
11
+ # **`positive` / `negative`** — not the "THUMBS_UP"/"THUMBS_DOWN" this used to document.
12
+ #
13
+ # `ai_summary_version_id` comes from `generatePageSummary`'s `item.id`.
9
14
  class SubmitFeedback < Logic::Mutation
10
- field_name :submitAiSummaryFeedback
15
+ SENTIMENTS = %w[positive negative].freeze
16
+
17
+ field_name :submitPageAiSummaryFeedback
11
18
 
12
19
  class_resolver :payload_class, 'Ecoportal::API::GraphQL::Payload::OkPayload'
13
20
 
21
+ def query(ai_summary_version_id:, sentiment:, **kargs, &block)
22
+ unless SENTIMENTS.include?(sentiment.to_s)
23
+ raise ArgumentError, "sentiment must be one of #{SENTIMENTS.join(' / ')}; got #{sentiment.inspect}"
24
+ end
25
+
26
+ super(
27
+ input: { aiSummaryVersionId: ai_summary_version_id, sentiment: sentiment.to_s },
28
+ **kargs,
29
+ &block
30
+ )
31
+ end
32
+
14
33
  private
15
34
 
16
35
  def basic_block(&block)
17
36
  payload_block = block || default_payload_block
18
37
  proc {
19
- mutation(aiSummaryVersionId: :id!, sentiment: :AiSummarySentimentEnum!) {
20
- submitAiSummaryFeedback(
21
- aiSummaryVersionId: :aiSummaryVersionId,
22
- sentiment: :sentiment,
23
- &payload_block
24
- )
38
+ mutation(input: :SubmitFeedbackInput!) {
39
+ submitPageAiSummaryFeedback(input: :input, &payload_block)
25
40
  }
26
41
  }
27
42
  end