eco-helpers 3.2.14 → 3.2.16

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/.ai-assistance/conventions/code-working-tree-protocol.md +176 -0
  3. data/.ai-assistance/scripts/token-logger.js +220 -0
  4. data/.ai-assistance/scripts/token-report.ts +158 -0
  5. data/.ai-assistance/scripts/token-session-start.js +66 -0
  6. data/.ai-assistance/skills/ep-ai-manager/SKILL.md +417 -0
  7. data/.ai-assistance/skills/ruby-scripting/SKILL.md +215 -0
  8. data/.ai-assistance/standards-version.json +10 -0
  9. data/.ai-assistance/token-budget.json +39 -0
  10. data/.claude/settings.json +103 -0
  11. data/.gitignore +2 -0
  12. data/CHANGELOG.md +17 -0
  13. data/CLAUDE.md +83 -0
  14. data/eco-helpers.gemspec +1 -1
  15. data/lib/eco/api/usecases/CLAUDE.md +78 -0
  16. data/lib/eco/api/usecases/default/pages.rb +30 -0
  17. data/lib/eco/api/usecases/graphql/CLAUDE.md +120 -0
  18. data/lib/eco/api/usecases/graphql/compat/ooze_redirect/dirty_array.rb +22 -0
  19. data/lib/eco/api/usecases/graphql/compat/ooze_redirect/field_patches.rb +241 -0
  20. data/lib/eco/api/usecases/graphql/compat/ooze_redirect/force_compat.rb +73 -0
  21. data/lib/eco/api/usecases/graphql/compat/ooze_redirect.rb +234 -0
  22. data/lib/eco/api/usecases/graphql/compat.rb +6 -0
  23. data/lib/eco/api/usecases/graphql/helpers/CLAUDE.md +79 -0
  24. data/lib/eco/api/usecases/graphql/samples/CLAUDE.md +76 -0
  25. data/lib/eco/api/usecases/graphql/samples/pages/CLAUDE.md +59 -0
  26. data/lib/eco/api/usecases/graphql/samples/pages/org_page/base.rb +41 -0
  27. data/lib/eco/api/usecases/graphql/samples/pages/org_page/dsl.rb +8 -0
  28. data/lib/eco/api/usecases/graphql/samples/pages/org_page.rb +7 -0
  29. data/lib/eco/api/usecases/graphql/samples/pages/page/base.rb +148 -0
  30. data/lib/eco/api/usecases/graphql/samples/pages/page/dsl.rb +38 -0
  31. data/lib/eco/api/usecases/graphql/samples/pages/page.rb +7 -0
  32. data/lib/eco/api/usecases/graphql/samples/pages.rb +7 -0
  33. data/lib/eco/api/usecases/graphql/samples.rb +1 -0
  34. data/lib/eco/api/usecases/graphql.rb +1 -0
  35. data/lib/eco/api/usecases/ooze_samples/ooze_base_case.rb +4 -0
  36. data/lib/eco/api/usecases/ooze_samples/register_update_case.rb +7 -1
  37. data/lib/eco/version.rb +1 -1
  38. metadata +31 -3
@@ -0,0 +1,76 @@
1
+ # usecases/graphql/samples
2
+
3
+ Built-in GraphQL sample base classes shipped with the gem.
4
+ These are abstract/semi-abstract classes that org scripts inherit from.
5
+ Concrete, CLI-integrated cases go in `usecases/default/` instead.
6
+
7
+ ---
8
+
9
+ ## Hierarchy convention
10
+
11
+ Each domain follows:
12
+ ```
13
+ samples/<domain>.rb ← namespace loader (may also BE the base class)
14
+ samples/<domain>/
15
+ <level>/
16
+ dsl.rb ← DSL concern — include in base, available to subclasses
17
+ base.rb ← Base class (inherits from GraphQL::Base or parent level)
18
+ <functional_level>.rb ← Optional: opinionated subclass, inherit directly
19
+ <functional_level>/
20
+ dsl.rb ← Further DSL for that functional level
21
+ ```
22
+
23
+ DSLs are always **concerns (modules)** to include — never classes.
24
+ Bases are **classes** with the scaffolding logic.
25
+ Functional levels add opinionated defaults on top of base.
26
+
27
+ ---
28
+
29
+ ## Contents
30
+
31
+ | File | Class | Purpose |
32
+ |------|-------|---------|
33
+ | `samples/location.rb` | `Samples::Location` | Location structure management |
34
+ | `samples/location/command.rb` | `Samples::Location::Command` | Apply location tree commands |
35
+ | `samples/location/service.rb` | `Samples::Location::Service` | Tree diffing and conversion service |
36
+ | `samples/contractors.rb` | `Samples::Contractors` | Contractor entity base case |
37
+ | `samples/contractors/dsl.rb` | `Contractors::DSL` | Contractor helper mixin |
38
+ | `samples/pages.rb` | `Samples::Pages` (namespace) | Page processing cases loader |
39
+ | `samples/pages/page/dsl.rb` | `Pages::Page::DSL` | SearchConf helpers mixin |
40
+ | `samples/pages/page/base.rb` | `Pages::Page::Base` | Register-scoped page iteration |
41
+ | `samples/pages/org_page/dsl.rb` | `Pages::OrgPage::DSL` | Org-page DSL (extends Page::DSL) |
42
+ | `samples/pages/org_page/base.rb` | `Pages::OrgPage::Base` | Org-wide page iteration |
43
+
44
+ ---
45
+
46
+ ## Difference: samples vs org-specific cases vs default
47
+
48
+ | Layer | Location | Purpose |
49
+ |---|---|---|
50
+ | **samples** (here) | `eco-helpers/lib/.../graphql/samples/` | Abstract base classes — org scripts inherit |
51
+ | **default** | `eco-helpers/lib/.../usecases/default/` | Concrete CLI-integrated cases for ALL orgs |
52
+ | **org-specific** | `multi_org_api/{org}/config/graphql_cases/` | Org-specific implementations |
53
+
54
+ Org scripts inherit from `samples/`, optionally via `default/` as an intermediate layer.
55
+
56
+ ---
57
+
58
+ ## Adding a new built-in sample
59
+
60
+ 1. Create the case file in `samples/`:
61
+ ```ruby
62
+ # lib/eco/api/usecases/graphql/samples/my_domain.rb
63
+ class Eco::API::UseCases::GraphQL::Samples::MyDomain < Eco::API::UseCases::GraphQL::Base
64
+ name 'my-domain-case'
65
+ type :other
66
+
67
+ def process
68
+ # ...
69
+ end
70
+ end
71
+ ```
72
+
73
+ 2. Add `require_relative 'samples/my_domain'` to `samples.rb`.
74
+
75
+ If the case is page-centric, inherit from `PageCase` instead of `Base` to get
76
+ pagination, KPI tracking, and `update_page` for free.
@@ -0,0 +1,59 @@
1
+ # samples/pages
2
+
3
+ Base classes for GraphQL-native page processing use cases.
4
+
5
+ ---
6
+
7
+ ## Structure
8
+
9
+ ```
10
+ pages/
11
+ page/
12
+ dsl.rb ← Page::DSL — SearchConf helpers mixin (sc, in_register, state_is, ...)
13
+ base.rb ← Page::Base — register-scoped page iteration + KPI scaffolding
14
+ org_page/
15
+ dsl.rb ← OrgPage::DSL — extends Page::DSL (org-wide helpers)
16
+ base.rb ← OrgPage::Base — org-wide iteration (no default register scope)
17
+ ```
18
+
19
+ ---
20
+
21
+ ## Inheritance
22
+
23
+ ```
24
+ GraphQL::Base
25
+
26
+ Samples::Pages::Page::Base (register-scoped, inherits Page::DSL)
27
+
28
+ Samples::Pages::OrgPage::Base (org-wide, overrides search_conf)
29
+
30
+ your org subclass
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Page::Base — register-scoped scripts
36
+
37
+ Override `process_page(page)` and optionally `search_conf`.
38
+ Set `register_id` and `batch_size` on the class.
39
+
40
+ ## OrgPage::Base — org-wide scripts
41
+
42
+ Same as Page::Base but `search_conf` starts empty.
43
+ Add your own filters via `super.filter(state_is(:active))` etc.
44
+
45
+ ---
46
+
47
+ ## Adding a functional level
48
+
49
+ If a common pattern emerges (e.g., "stage-submit scripts"), add:
50
+
51
+ ```
52
+ pages/page/
53
+ stage_submitter.rb ← Page::StageSubmitter < Page::Base
54
+ stage_submitter/
55
+ dsl.rb ← StageSubmitter::DSL
56
+ ```
57
+
58
+ Keep base.rb for the pure iteration scaffolding; put opinionated defaults in
59
+ the functional level so scripts can choose their entry point.
@@ -0,0 +1,41 @@
1
+ module Eco::API::UseCases::GraphQL::Samples::Pages
2
+ # Base class for **org-wide** page processing use cases.
3
+ #
4
+ # Identical to Page::Base but with no default register scope — search_conf
5
+ # starts empty (all org pages). Subclass adds filters via super.
6
+ #
7
+ # == When to use which
8
+ #
9
+ # Page::Base — one register, most scripts ("go through all pages in Reg X")
10
+ # OrgPage::Base — entire org (cross-register audits, archive sweeps, bulk ops)
11
+ #
12
+ # == Subclass interface
13
+ #
14
+ # class Custom::UseCase::ArchiveStaleDrafts < Eco::API::UseCases::GraphQL::Samples::Pages::OrgPage::Base
15
+ # name 'archive-stale-drafts'
16
+ # batch_size 100
17
+ #
18
+ # def search_conf
19
+ # super.filter(state_is(:draft))
20
+ # .filter(updated_since('2025-01-01'))
21
+ # end
22
+ #
23
+ # def process_page(page)
24
+ # return skip('already archived') if page.archived?
25
+ # log(:info) { "Archiving: #{page.name}" }
26
+ # graphql.page.archive(input: { id: page.id }) unless simulate?
27
+ # end
28
+ # end
29
+ class OrgPage::Base < Page::Base
30
+ name 'graphql-org-page-base'
31
+ type :other
32
+
33
+ require_relative 'dsl'
34
+ include Eco::API::UseCases::GraphQL::Samples::Pages::OrgPage::DSL
35
+
36
+ # No default register scope. Subclass adds filters via super.
37
+ def search_conf
38
+ sc.new
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,8 @@
1
+ module Eco::API::UseCases::GraphQL::Samples::Pages::OrgPage
2
+ # DSL concern for org-wide page use cases.
3
+ # Includes Page::DSL — all SearchConf helpers are available.
4
+ # Add org-page-specific helpers here as the pattern grows.
5
+ module DSL
6
+ include Eco::API::UseCases::GraphQL::Samples::Pages::Page::DSL
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ module Eco::API::UseCases::GraphQL::Samples::Pages
2
+ module OrgPage
3
+ end
4
+ end
5
+
6
+ require_relative 'org_page/dsl'
7
+ require_relative 'org_page/base'
@@ -0,0 +1,148 @@
1
+ module Eco::API::UseCases::GraphQL::Samples::Pages
2
+ # Base class for **register-scoped** page processing use cases.
3
+ #
4
+ # Provides the iteration + KPI scaffolding mirroring RegisterUpdateCase
5
+ # from OozeSamples, but working natively with the GraphQL stack.
6
+ #
7
+ # == Subclass interface
8
+ #
9
+ # class Custom::UseCase::UpdateRiskRating < Eco::API::UseCases::GraphQL::Samples::Pages::Page::Base
10
+ # name 'update-risk-rating'
11
+ # register_id 'REG_ABC123'
12
+ # batch_size 50
13
+ #
14
+ # # Add filters on top of the default register scope.
15
+ # def search_conf
16
+ # super.filter(state_is(:active))
17
+ # .filter(updated_since(options.dig(:filters, :from).to_s))
18
+ # end
19
+ #
20
+ # # Transform or act on each page; call update_page(page) to persist.
21
+ # def process_page(page)
22
+ # field = page.components.get_by_name('Risk Level')
23
+ # return skip('no risk field') unless field
24
+ # page.name = "[HIGH] #{page.name}" if field.value == 'High'
25
+ # update_page(page)
26
+ # end
27
+ # end
28
+ #
29
+ # == What the base provides
30
+ # * process_page(page) — override point (required)
31
+ # * search_conf — override point (optional; default scopes to register_id)
32
+ # * update_page(page) — from_model + simulate? guard + error tracking
33
+ # * skip(reason) — record a non-error skip
34
+ # * each_page — cursor-paginated org search
35
+ # * KPI tracking — total / processed / updated / skipped / failed
36
+ class Page::Base < Eco::API::UseCases::GraphQL::Base
37
+ name 'graphql-page-base'
38
+ type :other
39
+
40
+ require_relative 'dsl'
41
+ include Eco::API::UseCases::GraphQL::Samples::Pages::Page::DSL
42
+
43
+ class << self
44
+ def batch_size(size = nil)
45
+ @batch_size ||= 50
46
+ return @batch_size unless size
47
+ @batch_size = size
48
+ end
49
+
50
+ def register_id(id = nil)
51
+ @register_id = id if id
52
+ @register_id
53
+ end
54
+ end
55
+
56
+ attr_reader :total_pages, :processed_pages, :updated_pages
57
+ attr_reader :failed_pages, :skipped_pages
58
+
59
+ # Entry point — called by GraphQL::Base#main.
60
+ def process
61
+ init_kpis
62
+ each_page do |page|
63
+ process_page(page)
64
+ @processed_pages += 1
65
+ end
66
+ log_kpis
67
+ end
68
+
69
+ # == Subclass override points ==============================================
70
+
71
+ # Transform or act on one page. Call update_page(page) to persist changes.
72
+ def process_page(_page)
73
+ raise NotImplementedError, "Implement #process_page in #{self.class}"
74
+ end
75
+
76
+ # Return a SearchConf for the page search. Override to add filters.
77
+ # Default: scoped to register_id when set, otherwise all pages.
78
+ def search_conf
79
+ conf = sc.new
80
+ reg = self.class.register_id
81
+ conf = conf.filter(in_register(reg)) if reg
82
+ conf
83
+ end
84
+
85
+ protected
86
+
87
+ # Record a skip (not an error — the page was intentionally not processed).
88
+ def skip(reason = nil)
89
+ @skipped_pages += 1
90
+ log(:debug) { "Skipped#{reason ? ": #{reason}" : ''}" }
91
+ end
92
+
93
+ # Persist a page. Wraps Input::Page::Update.from_model, respects simulate?,
94
+ # and tracks KPIs. Returns nil on simulate or no-change; Response otherwise.
95
+ def update_page(page, **kargs)
96
+ if simulate?
97
+ @skipped_pages += 1
98
+ log(:debug) { "Simulate — would update page #{page.id}" }
99
+ return nil
100
+ end
101
+ response = graphql.pages.update(page, **kargs)
102
+ if response.nil?
103
+ @skipped_pages += 1
104
+ elsif response.success?
105
+ @updated_pages += 1
106
+ else
107
+ @failed_pages += 1
108
+ log(:error) { "Failed to update page #{page.id}: #{response.body}" }
109
+ end
110
+ response
111
+ end
112
+
113
+ # Cursor-paginated iteration over pages matching search_conf.
114
+ # Uses org search (currentOrganization.pages) — returns full PageUnion
115
+ # with patchVer and field IDs (required for update workflows).
116
+ def each_page(conf: search_conf, first: self.class.batch_size, &block)
117
+ graphql.pages.each(search_conf: conf.to_h, first: first) do |page|
118
+ @total_pages += 1
119
+ yield page
120
+ end
121
+ end
122
+
123
+ private
124
+
125
+ def init_kpis
126
+ @total_pages = 0
127
+ @processed_pages = 0
128
+ @updated_pages = 0
129
+ @failed_pages = 0
130
+ @skipped_pages = 0
131
+ end
132
+
133
+ def log_kpis
134
+ log(:info) { kpis_message }
135
+ end
136
+
137
+ def kpis_message
138
+ [
139
+ 'Run end:',
140
+ " * Pages found: #{total_pages}",
141
+ " * Pages processed: #{processed_pages}",
142
+ " * Updated: #{updated_pages}",
143
+ " * Skipped: #{skipped_pages}",
144
+ " * Failed: #{failed_pages}"
145
+ ].join("\n")
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,38 @@
1
+ module Eco::API::UseCases::GraphQL::Samples::Pages::Page
2
+ # DSL concern — included in Page::Base and available to all Page subclasses.
3
+ # Provides the SearchConf accessor and common filter shorthand methods.
4
+ #
5
+ # Include this in any class that needs SearchConf DSL access without
6
+ # inheriting the full Page::Base iteration scaffolding.
7
+ module DSL
8
+ private
9
+
10
+ # Lazy accessor for the SearchConf builder class.
11
+ # Resolved at runtime so the ecoportal-api-graphql gem is guaranteed to be loaded.
12
+ # Subclasses can also define a local constant for brevity:
13
+ # SearchConf = Ecoportal::API::GraphQL::Input::SearchConf
14
+ def sc
15
+ Ecoportal::API::GraphQL::Input::SearchConf
16
+ end
17
+
18
+ # Convenience: build a register-scoped filter object.
19
+ def in_register(*ids)
20
+ sc.in_register(*ids)
21
+ end
22
+
23
+ # Convenience: build a state equality filter.
24
+ def state_is(value)
25
+ sc[:state].is(value)
26
+ end
27
+
28
+ # Convenience: build an externalId equality filter.
29
+ def external_id_eq(value)
30
+ sc[:external_id].eq(value)
31
+ end
32
+
33
+ # Convenience: build an updated_at since filter.
34
+ def updated_since(iso8601, time_zone: 'UTC')
35
+ sc[:updated_at].since(iso8601, time_zone: time_zone)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,7 @@
1
+ module Eco::API::UseCases::GraphQL::Samples::Pages
2
+ module Page
3
+ end
4
+ end
5
+
6
+ require_relative 'page/dsl'
7
+ require_relative 'page/base'
@@ -0,0 +1,7 @@
1
+ module Eco::API::UseCases::GraphQL::Samples
2
+ module Pages
3
+ end
4
+ end
5
+
6
+ require_relative 'pages/page'
7
+ require_relative 'pages/org_page'
@@ -5,3 +5,4 @@ end
5
5
 
6
6
  require_relative 'samples/location'
7
7
  require_relative 'samples/contractors'
8
+ require_relative 'samples/pages'
@@ -10,4 +10,5 @@ end
10
10
  require_relative 'graphql/helpers'
11
11
  require_relative 'graphql/utils'
12
12
  require_relative 'graphql/base'
13
+ require_relative 'graphql/compat'
13
14
  require_relative 'graphql/samples'
@@ -224,6 +224,10 @@ class Eco::API::UseCases::OozeSamples::OozeBaseCase < Eco::API::Common::Loaders:
224
224
  return if options.dig(:feedback, :only_stats)
225
225
  return unless (patch = (patch_doc(entry) || {})['page'])
226
226
 
227
+ # Affirmative dry-run line so an empty/blank page no longer reads as a silent no-op.
228
+ # A create body carries :templateId (CreateFromTemplateInput); anything else is an update.
229
+ verb = patch.is_a?(Hash) && patch[:templateId] ? 'create' : 'update'
230
+ log(:info) { "[dry-run] would #{verb} #{object_reference(entry)} with:" }
227
231
  pp patch
228
232
  end
229
233
 
@@ -105,7 +105,13 @@ class Eco::API::UseCases::OozeSamples::RegisterUpdateCase < Eco::API::UseCases::
105
105
  def enqueue(object)
106
106
  return unless object.respond_to?(:id)
107
107
 
108
- unless object.is_a?(Ecoportal::API::V2::Page) or object.is_a?(Ecoportal::API::V2::Pages::PageStage)
108
+ # Accept v2 Page/PageStage, or any duck-typed entry that carries change-tracking
109
+ # (the GraphQL compat page responds to #dirty? and #as_update). The strict v2-class
110
+ # guard otherwise raised for GraphQL pages under OozeRedirect.
111
+ queueable = object.is_a?(Ecoportal::API::V2::Page) ||
112
+ object.is_a?(Ecoportal::API::V2::Pages::PageStage) ||
113
+ (object.respond_to?(:dirty?) && object.respond_to?(:as_update))
114
+ unless queueable
109
115
  msg = "Queuing is just for entries. Expecting Page or PageStage. Given: #{object.class}"
110
116
  raise ArgumentError, msg
111
117
  end
data/lib/eco/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Eco
2
- VERSION = '3.2.14'.freeze
2
+ VERSION = '3.2.16'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eco-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.14
4
+ version: 3.2.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
@@ -262,7 +262,7 @@ dependencies:
262
262
  version: '1.3'
263
263
  - - ">="
264
264
  - !ruby/object:Gem::Version
265
- version: 1.3.4
265
+ version: 1.3.9
266
266
  type: :runtime
267
267
  prerelease: false
268
268
  version_requirements: !ruby/object:Gem::Requirement
@@ -272,7 +272,7 @@ dependencies:
272
272
  version: '1.3'
273
273
  - - ">="
274
274
  - !ruby/object:Gem::Version
275
- version: 1.3.4
275
+ version: 1.3.9
276
276
  - !ruby/object:Gem::Dependency
277
277
  name: ecoportal-api-v2
278
278
  requirement: !ruby/object:Gem::Requirement
@@ -541,6 +541,15 @@ executables: []
541
541
  extensions: []
542
542
  extra_rdoc_files: []
543
543
  files:
544
+ - ".ai-assistance/conventions/code-working-tree-protocol.md"
545
+ - ".ai-assistance/scripts/token-logger.js"
546
+ - ".ai-assistance/scripts/token-report.ts"
547
+ - ".ai-assistance/scripts/token-session-start.js"
548
+ - ".ai-assistance/skills/ep-ai-manager/SKILL.md"
549
+ - ".ai-assistance/skills/ruby-scripting/SKILL.md"
550
+ - ".ai-assistance/standards-version.json"
551
+ - ".ai-assistance/token-budget.json"
552
+ - ".claude/settings.json"
544
553
  - ".gitignore"
545
554
  - ".idea/.gitignore"
546
555
  - ".markdownlint.json"
@@ -549,6 +558,7 @@ files:
549
558
  - ".ruby-version"
550
559
  - ".yardopts"
551
560
  - CHANGELOG.md
561
+ - CLAUDE.md
552
562
  - Gemfile
553
563
  - LICENSE
554
564
  - README.md
@@ -740,6 +750,7 @@ files:
740
750
  - lib/eco/api/session/config/tagtree.rb
741
751
  - lib/eco/api/session/config/workflow.rb
742
752
  - lib/eco/api/usecases.rb
753
+ - lib/eco/api/usecases/CLAUDE.md
743
754
  - lib/eco/api/usecases/base_case.rb
744
755
  - lib/eco/api/usecases/base_case/model.rb
745
756
  - lib/eco/api/usecases/base_case/type.rb
@@ -764,6 +775,7 @@ files:
764
775
  - lib/eco/api/usecases/default/meta.rb
765
776
  - lib/eco/api/usecases/default/meta/cli/graphql_schema_cli.rb
766
777
  - lib/eco/api/usecases/default/meta/graphql_schema.rb
778
+ - lib/eco/api/usecases/default/pages.rb
767
779
  - lib/eco/api/usecases/default/people.rb
768
780
  - lib/eco/api/usecases/default/people/amend.rb
769
781
  - lib/eco/api/usecases/default/people/amend/clean_unknown_tags_case.rb
@@ -825,8 +837,15 @@ files:
825
837
  - lib/eco/api/usecases/default_cases/update_case.rb
826
838
  - lib/eco/api/usecases/default_cases/upsert_case.rb
827
839
  - lib/eco/api/usecases/graphql.rb
840
+ - lib/eco/api/usecases/graphql/CLAUDE.md
828
841
  - lib/eco/api/usecases/graphql/base.rb
842
+ - lib/eco/api/usecases/graphql/compat.rb
843
+ - lib/eco/api/usecases/graphql/compat/ooze_redirect.rb
844
+ - lib/eco/api/usecases/graphql/compat/ooze_redirect/dirty_array.rb
845
+ - lib/eco/api/usecases/graphql/compat/ooze_redirect/field_patches.rb
846
+ - lib/eco/api/usecases/graphql/compat/ooze_redirect/force_compat.rb
829
847
  - lib/eco/api/usecases/graphql/helpers.rb
848
+ - lib/eco/api/usecases/graphql/helpers/CLAUDE.md
830
849
  - lib/eco/api/usecases/graphql/helpers/base.rb
831
850
  - lib/eco/api/usecases/graphql/helpers/base/case_env.rb
832
851
  - lib/eco/api/usecases/graphql/helpers/base/error_handling.rb
@@ -859,6 +878,7 @@ files:
859
878
  - lib/eco/api/usecases/graphql/helpers/location/tags_remap/tags_map.rb
860
879
  - lib/eco/api/usecases/graphql/helpers/location/tags_remap/tags_set.rb
861
880
  - lib/eco/api/usecases/graphql/samples.rb
881
+ - lib/eco/api/usecases/graphql/samples/CLAUDE.md
862
882
  - lib/eco/api/usecases/graphql/samples/contractors.rb
863
883
  - lib/eco/api/usecases/graphql/samples/contractors/dsl.rb
864
884
  - lib/eco/api/usecases/graphql/samples/location.rb
@@ -885,6 +905,14 @@ files:
885
905
  - lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/node_attr_maps.rb
886
906
  - lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/parser.rb
887
907
  - lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/output.rb
908
+ - lib/eco/api/usecases/graphql/samples/pages.rb
909
+ - lib/eco/api/usecases/graphql/samples/pages/CLAUDE.md
910
+ - lib/eco/api/usecases/graphql/samples/pages/org_page.rb
911
+ - lib/eco/api/usecases/graphql/samples/pages/org_page/base.rb
912
+ - lib/eco/api/usecases/graphql/samples/pages/org_page/dsl.rb
913
+ - lib/eco/api/usecases/graphql/samples/pages/page.rb
914
+ - lib/eco/api/usecases/graphql/samples/pages/page/base.rb
915
+ - lib/eco/api/usecases/graphql/samples/pages/page/dsl.rb
888
916
  - lib/eco/api/usecases/graphql/utils.rb
889
917
  - lib/eco/api/usecases/graphql/utils/sftp.rb
890
918
  - lib/eco/api/usecases/lib.rb