ecoportal-api-graphql 1.3.10 → 1.3.12

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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/.ai-assistance/code/diff_pairing_engine.md +243 -0
  3. data/.ai-assistance/code/filter_contract_matrix.md +177 -0
  4. data/.ai-assistance/code/graphql_domain_knowledge.md +20 -10
  5. data/.ai-assistance/code/template_diff_pairing_domain.md +175 -0
  6. data/.ai-assistance/code/workflow-command-guide.md +28 -0
  7. data/.ai-assistance/projects/ooze-graphql-native-migration/INVENTORY.md +136 -0
  8. data/.ai-assistance/projects/ooze-graphql-native-migration/TODO.md +6 -1
  9. data/.ai-assistance/projects/qa-services-delivery/DECISIONS.md +93 -0
  10. data/.ai-assistance/projects/qa-services-delivery/INTENT.md +76 -0
  11. data/.ai-assistance/projects/qa-services-delivery/PHASE3-SCOPE.md +115 -0
  12. data/.ai-assistance/projects/qa-services-delivery/ROADMAP.md +99 -0
  13. data/.ai-assistance/projects/qa-services-delivery/TODO.md +81 -0
  14. data/.ai-assistance/projects/template-automatic-build-maintenance/INTENT.md +87 -0
  15. data/.ai-assistance/projects/template-automatic-build-maintenance/TODO.md +108 -0
  16. data/.ai-assistance/projects/template-diff-deploy/INTENT.md +12 -0
  17. data/.ai-assistance/projects/template-diff-deploy/TODO.md +9 -0
  18. data/.ai-assistance/projects/template-maintenance/PHASE0-FINDINGS.md +93 -0
  19. data/.ai-assistance/projects/template-maintenance/README.md +14 -0
  20. data/.ai-assistance/skills/procedural-memory/SKILL.md +319 -0
  21. data/.ai-assistance/standards-version.json +21 -20
  22. data/CHANGELOG.md +119 -0
  23. data/CLAUDE.md +10 -0
  24. data/docs/self-docs/ARCHITECTURE.md +88 -0
  25. data/docs/self-docs/CHANGES.jsonl +7 -0
  26. data/docs/self-docs/CONVENTIONS.md +74 -0
  27. data/docs/self-docs/INTEGRATIONS.md +63 -0
  28. data/docs/self-docs/OVERVIEW.md +51 -0
  29. data/docs/self-docs/STATUS.md +69 -0
  30. data/docs/self-docs/self-docs-index.json +39 -0
  31. data/docs/worklog.md +256 -0
  32. data/ecoportal-api-graphql.gemspec +1 -1
  33. data/lib/ecoportal/api/common/graphql/model/diffable.rb +54 -54
  34. data/lib/ecoportal/api/graphql/base/action.rb +43 -43
  35. data/lib/ecoportal/api/graphql/base/contractor_entity/member_changes.rb +67 -67
  36. data/lib/ecoportal/api/graphql/base/page/data_field/collection.rb +7 -0
  37. data/lib/ecoportal/api/graphql/base/page/data_field/contractor_entities.rb +28 -28
  38. data/lib/ecoportal/api/graphql/base/page/data_field/file_field.rb +25 -25
  39. data/lib/ecoportal/api/graphql/base/page/data_field/image_gallery.rb +24 -24
  40. data/lib/ecoportal/api/graphql/base/page/data_field.rb +1 -1
  41. data/lib/ecoportal/api/graphql/base/page/section_collection.rb +85 -79
  42. data/lib/ecoportal/api/graphql/base/preset_view.rb +17 -17
  43. data/lib/ecoportal/api/graphql/base/register.rb +18 -18
  44. data/lib/ecoportal/api/graphql/builder/template_builder.rb +174 -0
  45. data/lib/ecoportal/api/graphql/builder.rb +17 -16
  46. data/lib/ecoportal/api/graphql/compat/filter_translator.rb +63 -28
  47. data/lib/ecoportal/api/graphql/concerns/page_compat.rb +51 -51
  48. data/lib/ecoportal/api/graphql/concerns.rb +14 -14
  49. data/lib/ecoportal/api/graphql/diff/change.rb +59 -0
  50. data/lib/ecoportal/api/graphql/diff/command_synthesizer.rb +329 -0
  51. data/lib/ecoportal/api/graphql/diff/cross_object_diff.rb +165 -0
  52. data/lib/ecoportal/api/graphql/diff/deploy.rb +121 -0
  53. data/lib/ecoportal/api/graphql/diff/id_resolver.rb +64 -0
  54. data/lib/ecoportal/api/graphql/diff/pairing/candidate.rb +32 -0
  55. data/lib/ecoportal/api/graphql/diff/pairing/engine.rb +173 -0
  56. data/lib/ecoportal/api/graphql/diff/pairing/ledger.rb +119 -0
  57. data/lib/ecoportal/api/graphql/diff/pairing/signals.rb +104 -0
  58. data/lib/ecoportal/api/graphql/diff/strategy.rb +113 -0
  59. data/lib/ecoportal/api/graphql/diff/version_diff.rb +332 -0
  60. data/lib/ecoportal/api/graphql/diff.rb +34 -0
  61. data/lib/ecoportal/api/graphql/file_upload/client.rb +181 -181
  62. data/lib/ecoportal/api/graphql/fragment/page.rb +85 -85
  63. data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +1 -0
  64. data/lib/ecoportal/api/graphql/input/action/update.rb +14 -14
  65. data/lib/ecoportal/api/graphql/input/contractor_entity/update.rb +41 -41
  66. data/lib/ecoportal/api/graphql/input/location_structure/apply_commands.rb +47 -47
  67. data/lib/ecoportal/api/graphql/input/location_structure/draft/add_commands.rb +49 -49
  68. data/lib/ecoportal/api/graphql/input/location_structure/update_command.rb +27 -27
  69. data/lib/ecoportal/api/graphql/input/search_conf.rb +436 -367
  70. data/lib/ecoportal/api/graphql/input/workflow_command/add_field.rb +27 -18
  71. data/lib/ecoportal/api/graphql/interface/location_structure/command.rb +30 -30
  72. data/lib/ecoportal/api/graphql/logic/input.rb +26 -26
  73. data/lib/ecoportal/api/graphql/mutation/action/archive.rb +1 -1
  74. data/lib/ecoportal/api/graphql/mutation/action/create.rb +1 -1
  75. data/lib/ecoportal/api/graphql/mutation/action/update.rb +1 -1
  76. data/lib/ecoportal/api/graphql/mutation/contractor_entity/create.rb +1 -1
  77. data/lib/ecoportal/api/graphql/mutation/contractor_entity/destroy.rb +1 -1
  78. data/lib/ecoportal/api/graphql/mutation/contractor_entity/update.rb +1 -1
  79. data/lib/ecoportal/api/graphql/mutation/kickstand/fail_workflow.rb +1 -1
  80. data/lib/ecoportal/api/graphql/mutation/kickstand/start_workflow.rb +1 -1
  81. data/lib/ecoportal/api/graphql/mutation/kickstand/stop_workflow.rb +1 -1
  82. data/lib/ecoportal/api/graphql.rb +1 -0
  83. data/lib/ecoportal/api/graphql_version.rb +1 -1
  84. data/tests/dump_template_model.rb +90 -0
  85. data/tests/validate_queries.rb +31 -9
  86. metadata +40 -3
@@ -1,54 +1,54 @@
1
- module Ecoportal
2
- module API
3
- module Common
4
- module GraphQL
5
- class Model
6
- module Diffable
7
- require_relative 'diffable/hash_diff_nesting'
8
- require_relative 'diffable/classic_diff_service'
9
- require_relative 'diffable/diff_service'
10
-
11
- DIFF_CLASS = DiffService
12
-
13
- # INSTANCE METHODS
14
-
15
- # @note **cascaded callbacks**
16
- # 1. Can **skip** rooted objects (where `root?` is `true`).
17
- # This is because nested rooted objects are usually look-ups
18
- # (not really part of the target model).
19
- # 2. Allow to redefine `as_update` on each model.
20
- # @param flat [Boolean] whether it should NOT perform a cascaded callback
21
- # througout all the instance objects of the model hierarchy (nested).
22
- # @param ignored [Array<String>] the keys that should be ignored, not part
23
- # of the result of `as_update`
24
- # @return [nil, Hash] the patch `Hash` model including only
25
- # the changes between `original_doc` and `doc`.
26
- def as_update(**kargs)
27
- diff_class.new(
28
- self,
29
- **kargs
30
- ).diff
31
- end
32
-
33
- # @note `cascaded` will be more accurate in a `GraphQL` scenario.
34
- # @return [Boolean] stating if there are changes.
35
- def dirty?(...)
36
- au = as_update(...)
37
-
38
- return false if au.nil?
39
- return false if au == {}
40
-
41
- true
42
- end
43
-
44
- private
45
-
46
- def diff_class
47
- self.class::DIFF_CLASS
48
- end
49
- end
50
- end
51
- end
52
- end
53
- end
54
- end
1
+ module Ecoportal
2
+ module API
3
+ module Common
4
+ module GraphQL
5
+ class Model
6
+ module Diffable
7
+ require_relative 'diffable/hash_diff_nesting'
8
+ require_relative 'diffable/classic_diff_service'
9
+ require_relative 'diffable/diff_service'
10
+
11
+ DIFF_CLASS = DiffService
12
+
13
+ # INSTANCE METHODS
14
+
15
+ # @note **cascaded callbacks**
16
+ # 1. Can **skip** rooted objects (where `root?` is `true`).
17
+ # This is because nested rooted objects are usually look-ups
18
+ # (not really part of the target model).
19
+ # 2. Allow to redefine `as_update` on each model.
20
+ # @param flat [Boolean] whether it should NOT perform a cascaded callback
21
+ # througout all the instance objects of the model hierarchy (nested).
22
+ # @param ignored [Array<String>] the keys that should be ignored, not part
23
+ # of the result of `as_update`
24
+ # @return [nil, Hash] the patch `Hash` model including only
25
+ # the changes between `original_doc` and `doc`.
26
+ def as_update(**kargs)
27
+ diff_class.new(
28
+ self,
29
+ **kargs
30
+ ).diff
31
+ end
32
+
33
+ # @note `cascaded` will be more accurate in a `GraphQL` scenario.
34
+ # @return [Boolean] stating if there are changes.
35
+ def dirty?(...)
36
+ au = as_update(...)
37
+
38
+ return false if au.nil?
39
+ return false if au == {}
40
+
41
+ true
42
+ end
43
+
44
+ private
45
+
46
+ def diff_class
47
+ self.class::DIFF_CLASS
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,43 +1,43 @@
1
- module Ecoportal
2
- module API
3
- class GraphQL
4
- module Base
5
- class Action < Logic::BaseModel
6
- root!
7
-
8
- passkey :id
9
- passthrough :altId
10
- passthrough :name, :description
11
- passthrough :age
12
-
13
- passarray :locationIds
14
-
15
- passthrough :status, :relativeStatus
16
- passboolean :archived, :attached, :standaloneAction
17
- passthrough :actionCategoryId
18
-
19
- passarray :fileContainerIds
20
-
21
- passarray :assignedPersonMemberIds
22
- passthrough :creatorId, :creatorUserId
23
- passthrough :updaterId, :updaterUserId
24
- passthrough :completerId
25
-
26
- passthrough :timeZone
27
- embeds_one :dueDate, klass: Base::DateTime
28
- embeds_one :reminderDate, klass: Base::DateTime
29
- embeds_one :createdAt, klass: Base::DateTime
30
- embeds_one :updatedAt, klass: Base::DateTime
31
- embeds_one :completedAt, klass: Base::DateTime
32
- embeds_one :openededAt, klass: Base::DateTime
33
- embeds_one :closedAt, klass: Base::DateTime
34
- embeds_one :dueOrClosedDate, klass: Base::DateTime
35
-
36
- passboolean :completed
37
- passthrough :closeDetail
38
- #passthrough :dueIn # only for templates
39
- end
40
- end
41
- end
42
- end
43
- end
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Base
5
+ class Action < Logic::BaseModel
6
+ root!
7
+
8
+ passkey :id
9
+ passthrough :altId
10
+ passthrough :name, :description
11
+ passthrough :age
12
+
13
+ passarray :locationIds
14
+
15
+ passthrough :status, :relativeStatus
16
+ passboolean :archived, :attached, :standaloneAction
17
+ passthrough :actionCategoryId
18
+
19
+ passarray :fileContainerIds
20
+
21
+ passarray :assignedPersonMemberIds
22
+ passthrough :creatorId, :creatorUserId
23
+ passthrough :updaterId, :updaterUserId
24
+ passthrough :completerId
25
+
26
+ passthrough :timeZone
27
+ embeds_one :dueDate, klass: Base::DateTime
28
+ embeds_one :reminderDate, klass: Base::DateTime
29
+ embeds_one :createdAt, klass: Base::DateTime
30
+ embeds_one :updatedAt, klass: Base::DateTime
31
+ embeds_one :completedAt, klass: Base::DateTime
32
+ embeds_one :openededAt, klass: Base::DateTime
33
+ embeds_one :closedAt, klass: Base::DateTime
34
+ embeds_one :dueOrClosedDate, klass: Base::DateTime
35
+
36
+ passboolean :completed
37
+ passthrough :closeDetail
38
+ #passthrough :dueIn # only for templates
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,67 +1,67 @@
1
- module Ecoportal
2
- module API
3
- class GraphQL
4
- module Base
5
- class ContractorEntity
6
- module MemberChanges
7
- def associate(*values, lead: false)
8
- ids = to_person_ids(*values)
9
-
10
- associatedPeopleIds.tap do |associated|
11
- associated.push!(*ids)
12
- next unless lead
13
-
14
- lead!(*ids)
15
- end
16
- end
17
-
18
- def dissassociate(*values)
19
- ids = to_person_ids(*values)
20
-
21
- associatedPeopleIds.tap do |associated|
22
- unlead!(*ids)
23
- associated.delete!(*ids)
24
- end
25
- end
26
-
27
- def lead!(*values)
28
- ids = to_person_ids(*values)
29
-
30
- leadContractorIds.tap do |leads|
31
- associate(*ids)
32
- leads.push!(*ids)
33
- end
34
- end
35
-
36
- def unlead!(*values)
37
- ids = to_person_ids(*values)
38
-
39
- leadContractorIds.tap do |leads|
40
- leads.delete!(*ids)
41
- end
42
- end
43
-
44
- private
45
-
46
- def to_person_ids(*values)
47
- to_person_id(values.flatten)
48
- end
49
-
50
- def to_person_id(value)
51
- case value
52
- when String
53
- value
54
- when Ecoportal::API::V1::Person
55
- value.id
56
- when Hash
57
- to_person_id(['id'])
58
- when Enumarable
59
- value.map {|val| to_person_id(val)}.compact
60
- end
61
- end
62
- end
63
- end
64
- end
65
- end
66
- end
67
- end
1
+ module Ecoportal
2
+ module API
3
+ class GraphQL
4
+ module Base
5
+ class ContractorEntity
6
+ module MemberChanges
7
+ def associate(*values, lead: false)
8
+ ids = to_person_ids(*values)
9
+
10
+ associatedPeopleIds.tap do |associated|
11
+ associated.push!(*ids)
12
+ next unless lead
13
+
14
+ lead!(*ids)
15
+ end
16
+ end
17
+
18
+ def dissassociate(*values)
19
+ ids = to_person_ids(*values)
20
+
21
+ associatedPeopleIds.tap do |associated|
22
+ unlead!(*ids)
23
+ associated.delete!(*ids)
24
+ end
25
+ end
26
+
27
+ def lead!(*values)
28
+ ids = to_person_ids(*values)
29
+
30
+ leadContractorIds.tap do |leads|
31
+ associate(*ids)
32
+ leads.push!(*ids)
33
+ end
34
+ end
35
+
36
+ def unlead!(*values)
37
+ ids = to_person_ids(*values)
38
+
39
+ leadContractorIds.tap do |leads|
40
+ leads.delete!(*ids)
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def to_person_ids(*values)
47
+ to_person_id(values.flatten)
48
+ end
49
+
50
+ def to_person_id(value)
51
+ case value
52
+ when String
53
+ value
54
+ when Ecoportal::API::V1::Person
55
+ value.id
56
+ when Hash
57
+ to_person_id(['id'])
58
+ when Enumarable
59
+ value.map {|val| to_person_id(val)}.compact
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -37,6 +37,13 @@ module Ecoportal::API::GraphQL::Base::Page
37
37
  pool.find { |f| f.label.to_s.downcase == label.to_s.downcase }
38
38
  end
39
39
 
40
+ # Find a field by its id (v2 compat: components.get_by_id — used by e.g. event-changes /
41
+ # TnG cases that resolve a field by reference_id). Returns the field or nil.
42
+ def get_by_id(id)
43
+ wanted = id.to_s
44
+ @fields.find { |f| f.id.to_s == wanted }
45
+ end
46
+
40
47
  # Raw doc array (v2 compat — scripts iterate secs_doc / flds_doc).
41
48
  def doc
42
49
  @fields.map(&:doc)
@@ -1,28 +1,28 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- # Contractor entity selector field.
4
- # Stores references to ContractorEntity records.
5
- class ContractorEntities < DataField
6
- passarray :contractors # each: { id:, name: }
7
-
8
- def contractor_entity_ids
9
- Array(contractors).map { |c| c.is_a?(Hash) ? c['id'] : c }.compact
10
- end
11
-
12
- def contractor_entity_ids=(ids)
13
- doc['contractors'] = Array(ids).map { |id_val| { 'id' => id_val } }
14
- end
15
-
16
- # v2 compat alias
17
- def value=(ids)
18
- self.contractor_entity_ids = ids
19
- end
20
-
21
- def as_input
22
- return nil unless dirty?
23
-
24
- { contractorEntities: { id: id, contractorEntityIds: contractor_entity_ids } }
25
- end
26
- end
27
- end
28
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ # Contractor entity selector field.
4
+ # Stores references to ContractorEntity records.
5
+ class ContractorEntities < DataField
6
+ passarray :contractors # each: { id:, name: }
7
+
8
+ def contractor_entity_ids
9
+ Array(contractors).map { |c| c.is_a?(Hash) ? c['id'] : c }.compact
10
+ end
11
+
12
+ def contractor_entity_ids=(ids)
13
+ doc['contractors'] = Array(ids).map { |id_val| { 'id' => id_val } }
14
+ end
15
+
16
+ # v2 compat alias
17
+ def value=(ids)
18
+ self.contractor_entity_ids = ids
19
+ end
20
+
21
+ def as_input
22
+ return nil unless dirty?
23
+
24
+ { contractorEntities: { id: id, contractorEntityIds: contractor_entity_ids } }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,25 +1,25 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- # File attachment field.
4
- # Writing requires a prior file upload to the REST upload endpoint
5
- # to obtain fileContainerIds — see the file-upload TODO in projects/TODO.md.
6
- # The file_container_ids= setter can be used once IDs are available.
7
- class FileField < DataField
8
- passarray :fileContainers # each: { id:, fileName:, ... }
9
-
10
- def file_container_ids
11
- Array(fileContainers).map { |c| c.is_a?(Hash) ? c['id'] : c }.compact
12
- end
13
-
14
- def file_container_ids=(ids)
15
- doc['fileContainers'] = Array(ids).map { |id_val| { 'id' => id_val } }
16
- end
17
-
18
- def as_input
19
- return nil unless dirty?
20
-
21
- { file: { id: id, fileContainerIds: file_container_ids } }
22
- end
23
- end
24
- end
25
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ # File attachment field.
4
+ # Writing requires a prior file upload to the REST upload endpoint
5
+ # to obtain fileContainerIds — see the file-upload TODO in projects/TODO.md.
6
+ # The file_container_ids= setter can be used once IDs are available.
7
+ class FileField < DataField
8
+ passarray :fileContainers # each: { id:, fileName:, ... }
9
+
10
+ def file_container_ids
11
+ Array(fileContainers).map { |c| c.is_a?(Hash) ? c['id'] : c }.compact
12
+ end
13
+
14
+ def file_container_ids=(ids)
15
+ doc['fileContainers'] = Array(ids).map { |id_val| { 'id' => id_val } }
16
+ end
17
+
18
+ def as_input
19
+ return nil unless dirty?
20
+
21
+ { file: { id: id, fileContainerIds: file_container_ids } }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,24 +1,24 @@
1
- module Ecoportal::API::GraphQL::Base::Page
2
- class DataField
3
- # Image gallery field.
4
- # Writing requires a prior file upload to the REST upload endpoint
5
- # to obtain fileContainerIds — see the file-upload TODO in projects/TODO.md.
6
- class ImageGallery < DataField
7
- passarray :fileContainers # each: { id:, fileName:, url:, ... }
8
-
9
- def file_container_ids
10
- Array(fileContainers).map { |c| c.is_a?(Hash) ? c['id'] : c }.compact
11
- end
12
-
13
- def file_container_ids=(ids)
14
- doc['fileContainers'] = Array(ids).map { |id_val| { 'id' => id_val } }
15
- end
16
-
17
- def as_input
18
- return nil unless dirty?
19
-
20
- { imageGallery: { id: id, fileContainerIds: file_container_ids } }
21
- end
22
- end
23
- end
24
- end
1
+ module Ecoportal::API::GraphQL::Base::Page
2
+ class DataField
3
+ # Image gallery field.
4
+ # Writing requires a prior file upload to the REST upload endpoint
5
+ # to obtain fileContainerIds — see the file-upload TODO in projects/TODO.md.
6
+ class ImageGallery < DataField
7
+ passarray :fileContainers # each: { id:, fileName:, url:, ... }
8
+
9
+ def file_container_ids
10
+ Array(fileContainers).map { |c| c.is_a?(Hash) ? c['id'] : c }.compact
11
+ end
12
+
13
+ def file_container_ids=(ids)
14
+ doc['fileContainers'] = Array(ids).map { |id_val| { 'id' => id_val } }
15
+ end
16
+
17
+ def as_input
18
+ return nil unless dirty?
19
+
20
+ { imageGallery: { id: id, fileContainerIds: file_container_ids } }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -54,7 +54,7 @@ module Ecoportal
54
54
  }.freeze
55
55
 
56
56
  passkey :id
57
- passthrough :label, :deindex
57
+ passthrough :label, :deindex, :genomeSignature
58
58
  # __typename is stored under the 'type' key after mapping
59
59
  passthrough :type
60
60