ecoportal-api-graphql 1.3.13 → 1.3.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 (275) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +87 -0
  3. data/lib/ecoportal/api/common/graphql/client.rb +0 -2
  4. data/lib/ecoportal/api/common/graphql/http_client.rb +6 -0
  5. data/lib/ecoportal/api/graphql/base/ai_summary_version.rb +17 -17
  6. data/lib/ecoportal/api/graphql/base/file_container.rb +14 -14
  7. data/lib/ecoportal/api/graphql/base/location_classification_type.rb +15 -15
  8. data/lib/ecoportal/api/graphql/base/location_structure.rb +27 -27
  9. data/lib/ecoportal/api/graphql/base/organization.rb +15 -15
  10. data/lib/ecoportal/api/graphql/base/page/task.rb +24 -0
  11. data/lib/ecoportal/api/graphql/base/page.rb +17 -16
  12. data/lib/ecoportal/api/graphql/base/template.rb +35 -0
  13. data/lib/ecoportal/api/graphql/base.rb +37 -35
  14. data/lib/ecoportal/api/graphql/builder/contractor_entity.rb +41 -41
  15. data/lib/ecoportal/api/graphql/compat/response.rb +35 -35
  16. data/lib/ecoportal/api/graphql/connection/action.rb +11 -11
  17. data/lib/ecoportal/api/graphql/connection/action_category.rb +11 -11
  18. data/lib/ecoportal/api/graphql/connection/contractor_entity.rb +11 -11
  19. data/lib/ecoportal/api/graphql/connection/page.rb +11 -11
  20. data/lib/ecoportal/api/graphql/connection/person_member.rb +11 -11
  21. data/lib/ecoportal/api/graphql/connection/preview_page.rb +11 -11
  22. data/lib/ecoportal/api/graphql/connection.rb +17 -17
  23. data/lib/ecoportal/api/graphql/file_upload/client.rb +21 -10
  24. data/lib/ecoportal/api/graphql/fragment/field_configuration.rb +38 -0
  25. data/lib/ecoportal/api/graphql/fragment/force.rb +14 -10
  26. data/lib/ecoportal/api/graphql/fragment/location_node.rb +26 -26
  27. data/lib/ecoportal/api/graphql/fragment/page_task.rb +39 -0
  28. data/lib/ecoportal/api/graphql/fragment/template.rb +51 -0
  29. data/lib/ecoportal/api/graphql/fragment.rb +3 -0
  30. data/lib/ecoportal/api/graphql/input/contractor_entity.rb +14 -14
  31. data/lib/ecoportal/api/graphql/input/preset_view/update.rb +16 -16
  32. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage.rb +18 -18
  33. data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +21 -21
  34. data/lib/ecoportal/api/graphql/input/workflow_command/edit_page.rb +28 -28
  35. data/lib/ecoportal/api/graphql/input/workflow_command/edit_page_creator_permissions.rb +18 -18
  36. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +23 -23
  37. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/date.rb +20 -20
  38. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/image_gallery.rb +20 -20
  39. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/people.rb +24 -24
  40. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/plain_text.rb +20 -20
  41. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/rich_text.rb +20 -20
  42. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/select.rb +20 -20
  43. data/lib/ecoportal/api/graphql/input/workflow_command/move_field.rb +18 -18
  44. data/lib/ecoportal/api/graphql/input/workflow_command/reorder_forces.rb +18 -18
  45. data/lib/ecoportal/api/graphql/input/workflow_command/reorder_section.rb +18 -18
  46. data/lib/ecoportal/api/graphql/input/workflow_command.rb +251 -251
  47. data/lib/ecoportal/api/graphql/input.rb +24 -24
  48. data/lib/ecoportal/api/graphql/logic/connection.rb +34 -34
  49. data/lib/ecoportal/api/graphql/model/page/task.rb +16 -0
  50. data/lib/ecoportal/api/graphql/model/page.rb +16 -15
  51. data/lib/ecoportal/api/graphql/model/person_member.rb +15 -15
  52. data/lib/ecoportal/api/graphql/model/template.rb +15 -0
  53. data/lib/ecoportal/api/graphql/model.rb +32 -30
  54. data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +45 -45
  55. data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +40 -40
  56. data/lib/ecoportal/api/graphql/mutation/contractor_entity.rb +14 -14
  57. data/lib/ecoportal/api/graphql/mutation/page/approve_review_task.rb +40 -40
  58. data/lib/ecoportal/api/graphql/mutation/page/batch_update_review_task.rb +38 -40
  59. data/lib/ecoportal/api/graphql/mutation/page/create_draft.rb +38 -40
  60. data/lib/ecoportal/api/graphql/mutation/page/delete_draft.rb +38 -40
  61. data/lib/ecoportal/api/graphql/mutation/page/execute_force_commands.rb +7 -7
  62. data/lib/ecoportal/api/graphql/mutation/page/execute_workflow_commands.rb +8 -7
  63. data/lib/ecoportal/api/graphql/mutation/page/publish_draft.rb +38 -40
  64. data/lib/ecoportal/api/graphql/mutation/page/reject_review_task.rb +40 -40
  65. data/lib/ecoportal/api/graphql/mutation/page/restart_review_task.rb +40 -40
  66. data/lib/ecoportal/api/graphql/mutation/page/undo_review_task.rb +40 -40
  67. data/lib/ecoportal/api/graphql/mutation/preset_view/destroy.rb +34 -35
  68. data/lib/ecoportal/api/graphql/mutation/register/destroy.rb +35 -35
  69. data/lib/ecoportal/api/graphql/mutation/smart_fill/generate.rb +36 -36
  70. data/lib/ecoportal/api/graphql/mutation/smart_fill/submit_feedback.rb +40 -40
  71. data/lib/ecoportal/api/graphql/mutation/smart_fill.rb +13 -13
  72. data/lib/ecoportal/api/graphql/mutation/template/create_related_page.rb +46 -46
  73. data/lib/ecoportal/api/graphql/mutation/template/destroy_related_page.rb +1 -1
  74. data/lib/ecoportal/api/graphql/mutation/template/update_information.rb +1 -1
  75. data/lib/ecoportal/api/graphql/mutation.rb +20 -20
  76. data/lib/ecoportal/api/graphql/payload/contractor_entity.rb +14 -14
  77. data/lib/ecoportal/api/graphql/payload/ok_payload.rb +36 -21
  78. data/lib/ecoportal/api/graphql/payload/page/draft.rb +26 -13
  79. data/lib/ecoportal/api/graphql/payload/page/review_task.rb +13 -13
  80. data/lib/ecoportal/api/graphql/payload/page/review_task_batch.rb +23 -0
  81. data/lib/ecoportal/api/graphql/payload/page.rb +20 -19
  82. data/lib/ecoportal/api/graphql/payload/preset_view.rb +15 -11
  83. data/lib/ecoportal/api/graphql/payload/register.rb +15 -11
  84. data/lib/ecoportal/api/graphql/payload/template/create_related_page.rb +1 -1
  85. data/lib/ecoportal/api/graphql/payload/template/destroy_related_page.rb +1 -1
  86. data/lib/ecoportal/api/graphql/payload/template/update_information.rb +1 -1
  87. data/lib/ecoportal/api/graphql/payload.rb +23 -23
  88. data/lib/ecoportal/api/graphql/query/location_structures.rb +57 -57
  89. data/lib/ecoportal/api/graphql/query/page.rb +45 -45
  90. data/lib/ecoportal/api/graphql/query/page_with_forces.rb +9 -3
  91. data/lib/ecoportal/api/graphql/query/pages_workflow_commands.rb +9 -3
  92. data/lib/ecoportal/api/graphql/query/register_preset_views.rb +78 -78
  93. data/lib/ecoportal/api/graphql/query.rb +27 -27
  94. data/lib/ecoportal/api/graphql.rb +9 -5
  95. data/lib/ecoportal/api/graphql_version.rb +1 -1
  96. metadata +9 -180
  97. data/.ai-assistance/bridge/CLAUDE.md +0 -338
  98. data/.ai-assistance/bridge/archive/.gitkeep +0 -0
  99. data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.inbox.md +0 -29
  100. data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.outbox.md +0 -18
  101. data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.inbox.md +0 -42
  102. data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.outbox.md +0 -115
  103. data/.ai-assistance/bridge/context/gemini-review-prompt.txt +0 -48
  104. data/.ai-assistance/bridge/context/gemini-review-response.md +0 -104
  105. data/.ai-assistance/bridge/context/project.md +0 -42
  106. data/.ai-assistance/bridge/inbox/.gitkeep +0 -0
  107. data/.ai-assistance/bridge/outbox/.gitkeep +0 -0
  108. data/.ai-assistance/bridge/outbox/request-for-standards-discovery.md +0 -48
  109. data/.ai-assistance/bridge/queue/.gitkeep +0 -1
  110. data/.ai-assistance/capabilities/CLAUDE.md +0 -27
  111. data/.ai-assistance/capabilities/assumptions-log.md +0 -80
  112. data/.ai-assistance/capabilities/code.md +0 -47
  113. data/.ai-assistance/capabilities/connectors.md +0 -37
  114. data/.ai-assistance/capabilities/cowork.md +0 -55
  115. data/.ai-assistance/code/OVERVIEW.md +0 -155
  116. data/.ai-assistance/code/data_fields.md +0 -242
  117. data/.ai-assistance/code/dependencies.md +0 -151
  118. data/.ai-assistance/code/diff_as_input.md +0 -234
  119. data/.ai-assistance/code/diff_pairing_engine.md +0 -243
  120. data/.ai-assistance/code/diff_service_deep_dive.md +0 -192
  121. data/.ai-assistance/code/ecoPortal_architecture/00_overview_and_index.md +0 -55
  122. data/.ai-assistance/code/ecoPortal_architecture/01_terminology_dictionary.md +0 -181
  123. data/.ai-assistance/code/ecoPortal_architecture/02_data_model.md +0 -192
  124. data/.ai-assistance/code/ecoPortal_architecture/03_api_layers.md +0 -147
  125. data/.ai-assistance/code/ecoPortal_architecture/04_graphql_queries_mutations.md +0 -277
  126. data/.ai-assistance/code/ecoPortal_architecture/05_page_workflows.md +0 -200
  127. data/.ai-assistance/code/ecoPortal_architecture/06_search_and_filters.md +0 -228
  128. data/.ai-assistance/code/ecoPortal_architecture/07_data_fields.md +0 -197
  129. data/.ai-assistance/code/ecoPortal_architecture/08_stages_sections.md +0 -243
  130. data/.ai-assistance/code/ecoPortal_architecture/09_people_contractors_locations.md +0 -196
  131. data/.ai-assistance/code/ecoPortal_architecture/10_forces_workflow_builder.md +0 -132
  132. data/.ai-assistance/code/ecoPortal_architecture/11_integration_gems.md +0 -187
  133. data/.ai-assistance/code/ecoPortal_architecture/12_ai_documentation_sources_gaps.md +0 -236
  134. data/.ai-assistance/code/ecoPortal_architecture/13_ai_infrastructure.md +0 -183
  135. data/.ai-assistance/code/ecoportal_schema_reference.md +0 -240
  136. data/.ai-assistance/code/filter_contract_matrix.md +0 -177
  137. data/.ai-assistance/code/graphql_domain_knowledge.md +0 -240
  138. data/.ai-assistance/code/refactoring/datafield-readwrite-shape-asymmetry.md +0 -71
  139. data/.ai-assistance/code/refactoring/opportunities.md +0 -251
  140. data/.ai-assistance/code/schema_analysis.md +0 -321
  141. data/.ai-assistance/code/search_filters.md +0 -868
  142. data/.ai-assistance/code/spec_coverage.md +0 -73
  143. data/.ai-assistance/code/template_diff_pairing_domain.md +0 -175
  144. data/.ai-assistance/code/workflow-command-guide.md +0 -466
  145. data/.ai-assistance/code/workflow-space.md +0 -353
  146. data/.ai-assistance/conventions/CLAUDE.md +0 -30
  147. data/.ai-assistance/conventions/code-working-tree-protocol.md +0 -199
  148. data/.ai-assistance/conventions/gitignore-rules.md +0 -42
  149. data/.ai-assistance/conventions/permission-guidance.md +0 -120
  150. data/.ai-assistance/integrations/README.md +0 -70
  151. data/.ai-assistance/integrations/gitkraken-mcp.md +0 -107
  152. data/.ai-assistance/integrations/gitlab-mcp.md +0 -123
  153. data/.ai-assistance/integrations/local-git.md +0 -60
  154. data/.ai-assistance/local_paths.example.md +0 -17
  155. data/.ai-assistance/projects/TODO.md +0 -118
  156. data/.ai-assistance/projects/api-v2-to-graphql-migration/DECISIONS.md +0 -168
  157. data/.ai-assistance/projects/api-v2-to-graphql-migration/INTENT.md +0 -60
  158. data/.ai-assistance/projects/api-v2-to-graphql-migration/TODO.md +0 -267
  159. data/.ai-assistance/projects/api-v2-to-graphql-migration/UPSTREAM.md +0 -53
  160. data/.ai-assistance/projects/api-v2-to-graphql-migration/notes/csv-template-pipeline-design.md +0 -102
  161. data/.ai-assistance/projects/api-v2-to-graphql-migration/notes/cutover-usecase-gap-audit.md +0 -139
  162. data/.ai-assistance/projects/compat-layer-audit/COMPAT_AUDIT.md +0 -244
  163. data/.ai-assistance/projects/dynamic-model-generation/INTENT.md +0 -93
  164. data/.ai-assistance/projects/eco-helpers-compat/INTENT.md +0 -244
  165. data/.ai-assistance/projects/eco-helpers-compat/MIGRATION_GUIDE.md +0 -266
  166. data/.ai-assistance/projects/eco-helpers-compat/TODO.md +0 -86
  167. data/.ai-assistance/projects/ecoportal-api-v2-doublemodel-review/INTENT.md +0 -101
  168. data/.ai-assistance/projects/graphql-agent/GAP_ANALYSIS.md +0 -177
  169. data/.ai-assistance/projects/ooze-graphql-native-migration/DECISIONS.md +0 -161
  170. data/.ai-assistance/projects/ooze-graphql-native-migration/INTENT.md +0 -125
  171. data/.ai-assistance/projects/ooze-graphql-native-migration/INVENTORY.md +0 -136
  172. data/.ai-assistance/projects/ooze-graphql-native-migration/RISKS.md +0 -126
  173. data/.ai-assistance/projects/ooze-graphql-native-migration/TODO.md +0 -261
  174. data/.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-06-30-cutover-workflow-deep-review.md +0 -122
  175. data/.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-07-01-forces-via-workflow-commands-miss-rca.md +0 -148
  176. data/.ai-assistance/projects/page-model/DECISIONS.md +0 -245
  177. data/.ai-assistance/projects/page-model/TODO.md +0 -190
  178. data/.ai-assistance/projects/qa-services-delivery/DECISIONS.md +0 -93
  179. data/.ai-assistance/projects/qa-services-delivery/INTENT.md +0 -76
  180. data/.ai-assistance/projects/qa-services-delivery/PHASE3-SCOPE.md +0 -115
  181. data/.ai-assistance/projects/qa-services-delivery/ROADMAP.md +0 -99
  182. data/.ai-assistance/projects/qa-services-delivery/TODO.md +0 -81
  183. data/.ai-assistance/projects/search-filter-builder/INTENT.md +0 -107
  184. data/.ai-assistance/projects/search-filter-builder/TODO.md +0 -131
  185. data/.ai-assistance/projects/template-automatic-build-maintenance/INTENT.md +0 -87
  186. data/.ai-assistance/projects/template-automatic-build-maintenance/TODO.md +0 -108
  187. data/.ai-assistance/projects/template-diff-deploy/INTENT.md +0 -12
  188. data/.ai-assistance/projects/template-diff-deploy/TODO.md +0 -9
  189. data/.ai-assistance/projects/template-maintenance/DESIGN.md +0 -134
  190. data/.ai-assistance/projects/template-maintenance/PHASE0-FINDINGS.md +0 -93
  191. data/.ai-assistance/projects/template-maintenance/README.md +0 -14
  192. data/.ai-assistance/projects/template-model-logic/CATEGORY_CATALOG.md +0 -236
  193. data/.ai-assistance/projects/template-model-logic/CLASSIFICATION_SPIKE.md +0 -243
  194. data/.ai-assistance/projects/template-model-logic/DESIGN_NOTE.md +0 -154
  195. data/.ai-assistance/projects/workflow-space/TODO.md +0 -213
  196. data/.ai-assistance/reinstall-claude-desktop-windows.md +0 -136
  197. data/.ai-assistance/scripts/CLAUDE.md +0 -150
  198. data/.ai-assistance/scripts/bridge-inbox-check.sh +0 -75
  199. data/.ai-assistance/scripts/bridge-init.sh +0 -86
  200. data/.ai-assistance/scripts/bridge-status.sh +0 -44
  201. data/.ai-assistance/scripts/capabilities-check.ts +0 -104
  202. data/.ai-assistance/scripts/check-outbox.sh +0 -43
  203. data/.ai-assistance/scripts/dep_graph.rb +0 -91
  204. data/.ai-assistance/scripts/lock-acquire.sh +0 -103
  205. data/.ai-assistance/scripts/lock-multi.sh +0 -124
  206. data/.ai-assistance/scripts/lock-queue.sh +0 -94
  207. data/.ai-assistance/scripts/setup-mcps.test.ts +0 -188
  208. data/.ai-assistance/scripts/setup-mcps.ts +0 -234
  209. data/.ai-assistance/scripts/task-complete.ts +0 -74
  210. data/.ai-assistance/scripts/task-create.ts +0 -75
  211. data/.ai-assistance/scripts/task-read.ts +0 -125
  212. data/.ai-assistance/scripts/token-logger.js +0 -220
  213. data/.ai-assistance/scripts/token-report.ts +0 -158
  214. data/.ai-assistance/scripts/token-session-start.js +0 -66
  215. data/.ai-assistance/skills/ai-instructions/SKILL.md +0 -48
  216. data/.ai-assistance/skills/code-specs/SKILL.md +0 -69
  217. data/.ai-assistance/skills/corporate-policies/SKILL.md +0 -201
  218. data/.ai-assistance/skills/dep-graph/SKILL.md +0 -139
  219. data/.ai-assistance/skills/ep-ai-manager/SKILL.md +0 -417
  220. data/.ai-assistance/skills/gemini-assist/SKILL.md +0 -63
  221. data/.ai-assistance/skills/gemini-assist/gemini-mcp-server.js +0 -205
  222. data/.ai-assistance/skills/gemini-assist/gemini_ask.py +0 -1
  223. data/.ai-assistance/skills/gemini-assist/gemini_ask.rb +0 -240
  224. data/.ai-assistance/skills/gemini-assist/prompts/cycle_end_review.txt +0 -25
  225. data/.ai-assistance/skills/graphql-schema-analysis/SKILL.md +0 -261
  226. data/.ai-assistance/skills/procedural-memory/SKILL.md +0 -319
  227. data/.ai-assistance/skills/project-cycle/SKILL.md +0 -177
  228. data/.ai-assistance/skills/project-self-docs/SKILL.md +0 -181
  229. data/.ai-assistance/skills/project-self-docs/scripts/self_docs_scan.py +0 -378
  230. data/.ai-assistance/skills/refactor/SKILL.md +0 -62
  231. data/.ai-assistance/skills/rubocop/SKILL.md +0 -93
  232. data/.ai-assistance/skills/ruby-scripting/SKILL.md +0 -215
  233. data/.ai-assistance/skills/spec-generation/SKILL.md +0 -72
  234. data/.ai-assistance/standards-version.json +0 -22
  235. data/.ai-assistance/token-budget.json +0 -32
  236. data/.ai-assistance/version.json +0 -39
  237. data/.claude/settings.json +0 -150
  238. data/.env.example +0 -18
  239. data/.gitattributes +0 -15
  240. data/.gitignore +0 -37
  241. data/.gitlab-ci.yml +0 -45
  242. data/.markdownlint.json +0 -4
  243. data/.rspec +0 -3
  244. data/.rubocop.yml +0 -121
  245. data/.ruby-version +0 -1
  246. data/.yardopts +0 -10
  247. data/CLAUDE.md +0 -243
  248. data/Gemfile +0 -30
  249. data/Rakefile +0 -90
  250. data/bin/console +0 -14
  251. data/bin/setup +0 -8
  252. data/bin/setup.ps1 +0 -6
  253. data/docs/self-docs/ARCHITECTURE.md +0 -88
  254. data/docs/self-docs/CHANGES.jsonl +0 -12
  255. data/docs/self-docs/COMPLIANCE.md +0 -79
  256. data/docs/self-docs/CONVENTIONS.md +0 -74
  257. data/docs/self-docs/INTEGRATIONS.md +0 -65
  258. data/docs/self-docs/OPERATIONS.md +0 -76
  259. data/docs/self-docs/OVERVIEW.md +0 -64
  260. data/docs/self-docs/STATUS.md +0 -73
  261. data/docs/self-docs/self-docs-index.json +0 -51
  262. data/docs/worklog.md +0 -977
  263. data/ecoportal-api-graphql.gemspec +0 -40
  264. data/scripts/auto-worker-scheduler.sh +0 -386
  265. data/tests/actions_get.rb +0 -7
  266. data/tests/contractor_entities_get.rb +0 -20
  267. data/tests/contractor_entity_create.rb +0 -19
  268. data/tests/contractor_entity_udpate.rb +0 -20
  269. data/tests/dump_page_model.rb +0 -74
  270. data/tests/dump_template_model.rb +0 -90
  271. data/tests/loc_structure_get.rb +0 -10
  272. data/tests/loc_structure_update.rb +0 -51
  273. data/tests/loc_structures_get.rb +0 -15
  274. data/tests/local_libs.rb +0 -20
  275. data/tests/validate_queries.rb +0 -127
@@ -1,177 +0,0 @@
1
- # GraphQL Agent Corpus — Gap Analysis
2
-
3
- *Analysed 2026-06-07 from staging corpus at `C:\claude\Projects\Claude AWS Platform\tmp\corpus\staging\success\graphql\`*
4
- *18 staging documents reviewed.*
5
-
6
- ---
7
-
8
- ## Critical — Breaks Agent Reliability
9
-
10
- | File | Issue | Fix |
11
- |------|-------|-----|
12
- | `2262499334_search-by-external-id.md` | Contains placeholders (`"graphqlwide760"`, `"jsonwide760"`) instead of actual query/variables | Replace with real contractor search examples |
13
- | `2262892608_registers-searches-and-templates.md` | Entirely empty after header — no content | Populate register structure, preset views, search config |
14
- | Agent instructions (absent) | No guidance that GraphQL queries are client-defined — agent will expect structural uniformity | Add "GraphQL is a Language" note (see below) |
15
-
16
- ---
17
-
18
- ## High — Agent Will Hallucinate Without Guidance
19
-
20
- ### Error handling — completely missing
21
- No error taxonomy. No error codes. No recovery patterns. The agent will invent error names
22
- and suggest incorrect recovery steps.
23
- - **Add:** 20–30 common error codes with cause and recovery (e.g. `patchVer` conflict,
24
- invalid field ID, permission denied, stale cursor)
25
-
26
- ### State machines — completely missing
27
- No documented states for Page, Stage, Action, Task. No valid transitions. Agent will
28
- suggest invalid state changes.
29
- - **Add:** State diagrams or transition tables for each entity
30
-
31
- ### Authorization — completely missing
32
- `canXXX` fields exist on every Page, Stage, Action. What they mean is never explained.
33
- - **Add:** `canXXX` field guide — when they return false, what the caller should do
34
-
35
- ### Filter syntax — incomplete and inaccurate
36
- The search filter docs show `fieldName` in examples but production queries use `key`.
37
- Filter operation names are snake_case (silent failure if CamelCase is used — no error,
38
- no results). `filters` should always be an Array.
39
- - **Add:** Complete filter operation reference with snake_case requirement explicit.
40
- See `.ai-assistance/code/search_filters.md` in `ecoportal-api-graphql`.
41
-
42
- ### Field ID lifecycle — missing
43
- Docs warn that field IDs change between template and instance, but give no algorithm for
44
- resolving them (when to `buildFromTemplate` first, when to look up by type+label, etc.)
45
- - **Add:** "Field ID Resolution" section — the two-step workflow and when each applies
46
-
47
- ### `updateMode` on actions — undocumented
48
- The UpdateAction mutation accepts `updateMode` but valid values are not documented.
49
- Agent will omit or guess (single / series / future / all).
50
- - **Add:** `updateMode` enum values with examples
51
-
52
- ---
53
-
54
- ## Medium — Gaps That Reduce Usefulness
55
-
56
- ### Covered but incomplete
57
-
58
- **Pages technical guide (`2235662347`):**
59
- - Missing: how `showHiddenData` interacts with field visibility
60
- - Missing: page state vs. stage state distinction
61
- - Missing: what `templatesOnly` does (returns templates as pages, not instances)
62
- - Missing: partial update semantics (sparse fields vs. full replacement)
63
-
64
- **Authentication (`1959788614`):**
65
- - `scope` shown as `[]` with no explanation
66
- - Token expiry and refresh failure handling missing
67
- - Security best practices for token storage missing
68
-
69
- **Searching pages (`1933639695`):**
70
- - Only 3 filter examples — no matrix of all filterable fields
71
- - No field-value filters (search by a specific data field value)
72
- - `mould_counter` appears in example with no explanation (deprecated; use `uid`)
73
-
74
- **Load actions (`1933901853`):**
75
- - Uses both `edges { node { ... } }` and `nodes` inconsistently
76
- - `Search` input type not documented alongside its usage
77
-
78
- **Create/Update page mutations:**
79
- - No guidance on transaction semantics (is a partial dataFields update atomic?)
80
- - Missing: what happens if one field update fails — does the mutation continue or abort?
81
-
82
- ### Not covered at all
83
-
84
- - Contractor entity lifecycle (create / approve / activate / archive)
85
- - Archive and unarchive page flows (compound mutation pattern)
86
- - File upload mechanics (separate from attach)
87
- - Bulk/batch operations
88
- - Visitor management integration
89
- - Page forces / risk management
90
- - Task workflow and status transitions
91
- - AI Summary field operations
92
- - Mailbox field operations
93
- - Cross-reference field deep guidance
94
- - People field — `cachedPeople` vs. `livePeople` distinction
95
- - Webhook / subscription patterns
96
- - Rate limiting and throttling
97
- - Cursor invalidation policy (how long cursors remain valid)
98
- - `deindex` and field visibility flags semantics
99
-
100
- ---
101
-
102
- ## Accuracy Concerns
103
-
104
- | File | Issue |
105
- |------|-------|
106
- | `1931575325_updatepage.md` | Example variables may reference `templateId` where `id` (page ID) is expected |
107
- | `1928855618_createaction.md` | Response structure example (`item: { ... }`) may not match actual wrapper |
108
- | `2235662347_graphql-pages-technical-guide.md` | Refers to `pageUnionCommonFragment` but fragment definition is in a separate doc with no cross-link |
109
- | Multiple | Date formats mixed (ISO8601 with Z vs. with +offset) — no guidance on when each is correct |
110
- | Multiple | Broken Confluence external links (opaque IDs, unresolvable outside Confluence) |
111
-
112
- ---
113
-
114
- ## Structural Issues
115
-
116
- 1. **No agent preamble.** There is no document that tells the agent the most important
117
- invariants: GraphQL variability, silent filter failures, two-step field ID resolution,
118
- compound mutation pattern. These must be added as explicit agent instructions, not
119
- buried in examples.
120
-
121
- 2. **No cross-reference index.** `CommonPageUnion` is referenced in 6+ documents but
122
- defined in only one. An agent cannot reliably find what it needs.
123
-
124
- 3. **No versioning or timestamps.** The agent cannot tell if a doc reflects the current
125
- schema or an old version. Schema changes may invalidate examples silently.
126
-
127
- 4. **Inconsistent example depth.** Some mutations show full request + response; others
128
- only show the query. Agent will fill in gaps incorrectly.
129
-
130
- 5. **Fragment defined but not explained.** `CommonPageUnion` shows the full GraphQL but
131
- nowhere explains what `$content`, `$only_content`, `$fields` actually control in
132
- human terms (with examples of before/after).
133
-
134
- ---
135
-
136
- ## Recommended Agent Preamble (add to system prompt or corpus index)
137
-
138
- ```
139
- You are assisting with the EcoPortal GraphQL API. Key invariants:
140
-
141
- 1. GraphQL queries are client-defined. The same resource can be queried many ways.
142
- Variability in examples is intentional. Multiple mutations in one request (executed
143
- in order) is valid and used for stateless middleware clients.
144
-
145
- 2. Filter operations are snake_case strings. CamelCase silently returns no results.
146
- Always use: exact_filter, date_filter, and_filter, or_filter, register_filter.
147
- The `filters` value should always be an Array.
148
-
149
- 3. Page creation requires a 2-step sequence:
150
- (a) buildFromTemplate → get field IDs from the built draft
151
- (b) createFromTemplate → use those field IDs in dataFields.updates
152
-
153
- 4. Page update requires:
154
- (a) Fetch current page → get patchVer + current field IDs
155
- (b) updatePage → include patchVer (required for concurrency control)
156
-
157
- 5. The CommonPageUnion fragment ($fields/$content/$only_content variables) is the
158
- standard pattern for fetching full page data. Use it for all page read operations.
159
-
160
- 6. Register search (previewPages) is Elasticsearch — fast but no field IDs.
161
- Org search (pages) is DB — slow (~3s/page) but complete data including field IDs.
162
- ```
163
-
164
- ---
165
-
166
- ## Recommended Additions Priority
167
-
168
- 1. Error taxonomy (codes, causes, recovery)
169
- 2. State machines (Page, Stage, Action, Task)
170
- 3. Field type matrix (all 20 types, validation, modifiers)
171
- 4. Full contractor management (currently broken/empty)
172
- 5. Authorization guide (`canXXX` meanings)
173
- 6. Archive/unarchive patterns
174
- 7. File upload guide
175
- 8. Complete filter fieldName reference
176
- 9. `updateMode` enum for actions
177
- 10. Cursor invalidation policy
@@ -1,161 +0,0 @@
1
- # Decisions — Ooze → Native GraphQL Migration
2
-
3
- Seeded with the founding architectural decisions. Append per-case parity results and any
4
- new decisions as the project executes. Never delete entries — history matters.
5
-
6
- ---
7
-
8
- ## [2026-06-30] Strangler-fig migration, one case at a time
9
-
10
- **Context:** The ooze use-case stack runs on APIv2 via the `OozeRedirect` runtime shim. We
11
- need it on native GraphQL, but a big-bang rewrite would (a) risk all live customer scripts
12
- at once and (b) collide with the in-flight `fix/ooze-redirect-faithful-dryrun` work.
13
-
14
- **Options considered:**
15
- 1. Big-bang rewrite of the whole ooze tree.
16
- 2. Keep the shim indefinitely.
17
- 3. Strangler-fig: build native classes beside the old ones, migrate one case at a time,
18
- each parity-gated, retiring shim code incrementally.
19
-
20
- **Decision:** Option 3 (strangler-fig), sequenced parent-before-child along the inheritance
21
- tree, gated by the A/B parity harness per case.
22
-
23
- **Reason:** Incremental, reversible, keeps live scripts working throughout, and lets us
24
- delete shim code in safe slices instead of one terrifying commit.
25
-
26
- **Consequences:** Old and new implementations coexist for the duration; the inventory
27
- partition (Phase 0) is the master schedule; each phase has an explicit parity gate.
28
-
29
- ---
30
-
31
- ## [2026-06-30] Native classes are the REAL implementation — NOT a monkeypatch
32
-
33
- **Context:** The current approach (`OozeRedirect.included` → `FieldPatches.apply!` +
34
- `base.prepend(Infrastructure)`) is a monkeypatch: it reopens v2 field classes globally and
35
- prepends behaviour onto the host case. The developer explicitly corrected the design:
36
- **do NOT keep reopening/patching classes ("patch at the end of each class").**
37
-
38
- **Options considered:**
39
- 1. Continue patching: make the GraphQL/samples classes by reopening the OozeSamples classes.
40
- 2. Make the new `graphql/samples/pages/*` classes the canonical implementation; old names
41
- become thin subclasses/delegators.
42
-
43
- **Decision:** Option 2. The native `GraphQL::Samples::Pages::*` class holds the real logic.
44
- `Eco::API::UseCases::OozeSamples::*` names are redefined as thin subclasses (or delegators)
45
- of the native class.
46
-
47
- **Reason:** Monkeypatching is what produced the 2026-06-30 KPI/dry-run-loss bug (a patched
48
- control-flow method silently diverged from the base loop). A real class with an explicit
49
- loop has one source of truth and is testable in isolation. Subclassing is a stable,
50
- well-understood compatibility idiom; runtime class reopening is not.
51
-
52
- **Consequences:** `FieldPatches`' global v2-class reopening (`patch_v2_type_dispatch!`) and
53
- the GraphQL field `prepend`s become unnecessary — native cases dispatch on GraphQL types
54
- directly. They are removed as the last case needing them is flipped (Phase 7).
55
-
56
- ---
57
-
58
- ## [2026-06-30] Preserve the OozeSamples public class names as the BC surface
59
-
60
- **Context:** Downstream customer scripts subclass/include the public names
61
- (`OozeSamples::TargetOozesUpdateCase`, `RegisterUpdateCase`, `Helpers::Creatable`,
62
- `RegisterExportCase`, etc.) and define override points (`process_ooze`, `search`,
63
- `filters`, `custom_processing`, `excluded_field_hooks`). The include-shim's whole value is
64
- that scripts change **nothing** today.
65
-
66
- **Decision:** The public `OozeSamples::*` / `OozeCases::*` names, their `name '...'`
67
- registrations, `type :other`, class-level `batch_size`/`register_id`, attr_readers, and
68
- every documented override point are **preserved exactly**. They resolve to the native
69
- implementation via subclass/delegation.
70
-
71
- **Reason:** Zero-script-edit is the explicit success criterion. The names are the contract.
72
-
73
- **Consequences:** Phase 0 must inventory every include/subclass site and override-method
74
- set so the native classes expose identical surfaces. Any unavoidable script edit is a goal
75
- regression → log here and confirm with Oscar before proceeding.
76
-
77
- ---
78
-
79
- ## [2026-06-30] Per-case parity gating via the A/B harness before flipping
80
-
81
- **Context:** Each migrated case changes the execution backend for real customer data. We
82
- need objective proof of equivalence before flipping the public name.
83
-
84
- **Decision:** Before flipping any old name to the native class, the case must be
85
- **parity-proven** against the existing v2 case using the team's A/B parity harness on the
86
- `mini` test org (read-only parity first, then writes). The recorded result is the gate.
87
-
88
- **Reference:** memory `project-parity-test-plan` — all-21-DataField-type template in `mini`,
89
- (1) A/B standalone harness (e.g. `mini/graphql_parity/`) reading/writing through both
90
- `ecoportal-api-v2` and `Ecoportal::API::GraphQL` + `Compat::Pages`, diffed by the field
91
- matrix; (2) eco-helpers session-backend swap re-running a real script unchanged. Also
92
- `.ai-assistance/projects/eco-helpers-compat/`.
93
-
94
- **Reason:** The 21-type field matrix gives a concrete pass/fail spec; the live-script swap
95
- proves the production path. Cheaper than discovering divergence in a customer run.
96
-
97
- **Consequences:** Phase 0 captures v2 baselines (the "A" side); the harness must exist
98
- before Phase 2 (built in Phase 0 if not). Each phase records its parity result as a dated
99
- entry in this log.
100
-
101
- ---
102
-
103
- ## [2026-06-30] Sequence: RegisterUpdateCase + Creatable, then TargetOozesUpdateCase, first
104
-
105
- **Context:** Two cases are already exercised in the live cutover: act-gov TOOCS coding
106
- (`TargetOozesUpdateCase`) and jamestrong CANS upsert (`RegisterUpdateCase` +
107
- `Helpers::Creatable`). `TargetOozesUpdateCase` **inherits** `RegisterUpdateCase`.
108
-
109
- **Decision:** Migrate the native register base + `Creatable` first (Phase 2, CANS), then
110
- `TargetOozesUpdateCase` (Phase 3, TOOCS), because the child cannot be native until its
111
- parent is.
112
-
113
- **Reason:** Highest live value, and the inheritance order forces parent-first. These two
114
- also surface the full KPI/queue/dedup/dry-run/submit machinery, de-risking later cases.
115
-
116
- **Consequences:** Phase 1 (shared concerns) must land first so both cases stay thin.
117
-
118
- ---
119
-
120
- ## [2026-06-30] Forces-dependent cases are HELD pending a Phase 0 live readiness test (not assumed-blocked)
121
-
122
- **Context (corrected 2026-06-30):** the GraphQL force endpoint is NOT read-only or missing —
123
- the gem ships both `Query::PageWithForces` (read) AND `Mutation::Page::ExecuteForceCommands`
124
- → `executeWorkflowCommands` (write: `editForce`/`addBinding`/`removeBinding`/`removeForce`).
125
- What is unconfirmed: `OozeRedirect.force_support?` is hard-wired `false`, and a (possibly stale)
126
- `ooze_redirect.rb` comment claims `PageWithForces` fails schema validation / backend "in
127
- progress". `ooze_redirect.rb` lists ~50% of all ooze cases as force-dependent.
128
-
129
- **Decision:** Do NOT assume forces are blocked. Phase 0 **live-tests** read + a no-op write
130
- against a real org. If it passes, forces are IN scope and those cases migrate normally. If it
131
- fails, they are partitioned **"migratable now"** vs **"blocked on forces"** and stay on the v2
132
- path; `force_compat.rb` / the v2 fallback is retained **only** for that holdout until the
133
- endpoint is fixed.
134
-
135
- **Blocked-on-forces seed list (from `ooze_redirect.rb`):** act-gov (5× `20240130_act_*`,
136
- `rearrage_page_sites`), briscoes (`remove_induction_sections`, `310524_Briscoes_Remove_Tasks`),
137
- chorus (4× `audit_update`), hcc (`update_enterprise_risk`), lic (`update_life_cycle_force`),
138
- mitre10 (`rich_text_update`, `update_location_force`, `updating_template`), npdc
139
- (`contractor_title_force`, `risk_titile_force`, `fix_title_syncing`, `reminder_date_fields`,
140
- `10092024_NPDC_CP_Add_Force`), profile-group (`int_training_review`,
141
- `20231026_profile_wellness`), turners-growers (`event_changes`, `inj_cost_calc`,
142
- `remove_line_force`), twg (`hide_attached_risks`, `add_new_force`).
143
-
144
- **Reason:** No endpoint = no native path. Forcing it would either break or require fetching
145
- via the broken force query for every case (the exact trap `force_support?` guards against).
146
-
147
- **Consequences:** This is a **hard external dependency**. The project completes "Phase 7"
148
- with the forces holdout explicitly documented, not deleted. Track the endpoint's arrival as
149
- the trigger for the follow-up forces-migration project.
150
-
151
- ---
152
-
153
- ## Per-case parity results (append as completed)
154
-
155
- <!-- Template:
156
- ## [DATE] Parity result — <CaseName>
157
- **Harness run:** <link/path to A/B output, e.g. baselines/<case>.txt vs native run>
158
- **Field matrix:** <pass/fail per relevant DataField type>
159
- **Live script re-run:** <org/script, unchanged? parity?>
160
- **Decision:** flip / hold / fix-first
161
- -->
@@ -1,125 +0,0 @@
1
- # Project: Ooze Use-Cases → Native GraphQL Migration (strangler-fig)
2
-
3
- **Created:** 2026-06-30
4
- **Status:** active
5
- **Primary repo:** `eco-helpers` (`C:\ruby_scripts\git\eco-helpers`)
6
- **Companion repo:** `ecoportal-api-graphql` (`C:\ruby_scripts\git\ecoportal-api-graphql`)
7
- **Branch (eco-helpers):** `feature/ooze-graphql-native-migration` (cut from current `fix/ooze-redirect-faithful-dryrun` once that merges)
8
- **Target branch:** `master` (eco-helpers) / `main` (gem)
9
-
10
- > **Why this plan lives in the gem repo:** `eco-helpers` has no `.ai-assistance/projects/`
11
- > folder. The team's project-cycle structure is hosted in `ecoportal-api-graphql`
12
- > (alongside the related `eco-helpers-compat` project), so this plan is committed here
13
- > for continuity. **The code work, however, is almost entirely in `eco-helpers`.**
14
- > Cross-reference: `.ai-assistance/projects/eco-helpers-compat/` (the compat layer this
15
- > migration eventually retires the *shim half* of).
16
-
17
- ---
18
-
19
- ## Goal
20
-
21
- Migrate the eco-helpers **ooze use-case stack** off the transitional APIv2 `OozeRedirect`
22
- monkeypatch shim and onto **native GraphQL use-case classes**, incrementally, one case at a
23
- time, using a strangler-fig approach.
24
-
25
- The new native implementations live under
26
- `lib/eco/api/usecases/graphql/samples/pages/*` (cases) and
27
- `lib/eco/api/usecases/graphql/helpers/pages/*` (shared concerns). The **existing public
28
- class names** under `Eco::API::UseCases::OozeSamples::*` are preserved as the
29
- backwards-compatibility surface — they become thin subclasses / delegators of the native
30
- classes. Downstream customer scripts keep working with **zero edits**, exactly as the
31
- include-shim achieves today.
32
-
33
- ---
34
-
35
- ## Motivation
36
-
37
- ### The shim is fragile and lossy
38
-
39
- `OozeRedirect` (`lib/eco/api/usecases/graphql/compat/ooze_redirect.rb` +
40
- `ooze_redirect/{dirty_array,field_patches,force_compat}.rb`) is a **runtime monkeypatch**:
41
-
42
- - `OozeRedirect.included(base)` calls `FieldPatches.apply!`, which **reopens** v2 field
43
- classes (`PlainTextField`, `SelectionField`, `ReferenceField`, `PeopleField`,
44
- `NumberField`) to make `===` / `is_a?` lie, and `prepend`s anonymous modules onto the
45
- GraphQL field classes (`Base::Page::DataField::{People,CrossReference,Select}`) and
46
- `Interface::BasePage`. These patches are **global, process-wide, and order-sensitive**.
47
- - It then `base.prepend(Infrastructure)` to override instance methods on the host case.
48
-
49
- **The recent bug (2026-06-30, captured in memory `session-handoff-ooze-redirect-dryrun`):**
50
- an earlier version of the shim's `Infrastructure` module **replaced whole control-flow
51
- methods** (`with_each_entry`, `update_ooze`, and wrapped `process_ooze`) rather than
52
- adapting only the leaf v2 operations. Effects observed on the act-gov (toocs) and
53
- jamestrong (cans) `-simulate` runs:
54
-
55
- - KPI counters (Search / Retrieved / Updated / Created) all read **0** — the base loop's
56
- increments were bypassed.
57
- - The dry-run diff **never printed** — the compat `process_ooze` did `return if simulate?`
58
- with no feedback, and the base `display_patch` / `backup_patch!` / `dirty?` read
59
- `patch_doc(ooze)['page']` while the gem's `Compat::Pages#get_body` returned a **flat**
60
- `as_update` (no `'page'` key) → `"No changes to update"` misfired.
61
-
62
- That bug was patched on `fix/ooze-redirect-faithful-dryrun` by **slimming the shim back to
63
- leaf adaptations and reusing the base loop** (gem: `get_body` → `{ 'page' => as_update }`
64
- and `update` folds captured submit flags; eco-helpers: removed the control-flow overrides).
65
- But the episode proves the structural point: **a monkeypatch that has to second-guess the
66
- host class's control flow is intrinsically dangerous.** Every future change to the
67
- OozeSamples base loop risks silently re-breaking the redirect, and vice-versa.
68
-
69
- ### Native classes are the durable answer
70
-
71
- Making the **GraphQL samples the real implementation** — with their own explicit loop, KPI
72
- tracking, dry-run feedback, and field access — removes the need to patch v2 classes or
73
- intercept the host's control flow at all. The old names survive purely as a compatibility
74
- veneer (subclass / delegate), which is a stable, well-understood Ruby idiom.
75
-
76
- ---
77
-
78
- ## Scope
79
-
80
- ### In scope
81
-
82
- - New native GraphQL use-case classes under `lib/eco/api/usecases/graphql/samples/pages/*`,
83
- mirroring the OozeSamples case tree (the **migratable-now** subset — see Risks).
84
- - Shared concerns extracted to `lib/eco/api/usecases/graphql/helpers/pages/*`
85
- (creatable, ooze-handlers, shortcuts, filters, rescuable, dirty/patch feedback).
86
- - Specs **in eco-helpers** for each native counterpart, written **before/with** the class
87
- (specs-first / parity-proving).
88
- - Re-pointing the old `OozeSamples::*` names to delegate to / subclass the native classes,
89
- **case by case**, behind per-case parity gating.
90
- - Per-case removal of the now-dead redirect code (the relevant `Infrastructure` overrides
91
- and `FieldPatches` entries) once a case is flipped.
92
- - Final removal of the `OozeRedirect` shim entirely once all migratable cases are flipped.
93
-
94
- ### Out of scope (non-goals)
95
-
96
- - **Force / binding-dependent cases.** ~50% of ooze cases use `target.forces` /
97
- `force.bindings` / `force.custom_script`. The gem DOES ship GraphQL force client code for
98
- both read (`Query::PageWithForces`) and write (`executeWorkflowCommands`:
99
- `editForce`/`addBinding`/`removeBinding`/`removeForce`), but it is gated OFF
100
- (`OozeRedirect.force_support?` hard-wired `false`) and end-to-end readiness is UNCONFIRMED.
101
- These cases are **held pending a Phase 0 live readiness test** — in scope if it passes, on
102
- the v2 path if it fails. See the Risks section.
103
- - Rewriting customer scripts. Scripts must not change. If a script *must* change, that is a
104
- decision to log in DECISIONS.md and confirm with Oscar — it is a regression of the goal.
105
- - Template mutation, Workflow Builder, webhooks/subscriptions (separate projects).
106
- - The `eco-helpers-compat` gem-side compat layer itself (`Compat::Pages`,
107
- `Compat::Registers`, `StageView`) stays — the native cases call it. This project retires
108
- the **OozeRedirect monkeypatch**, not the compat façade.
109
-
110
- ---
111
-
112
- ## Success Criteria
113
-
114
- 1. `TargetOozesUpdateCase` and `RegisterUpdateCase` (+ `Helpers::Creatable`) run on native
115
- GraphQL classes, parity-proven against the v2 path via the A/B harness, with the old
116
- names still resolving and the two live cutover scripts (act-gov TOOCS, jamestrong CANS)
117
- running **unchanged**.
118
- 2. Every migratable OozeSamples case has a native counterpart, a passing spec suite, and a
119
- recorded parity result before its name is flipped.
120
- 3. The `OozeRedirect` shim (and its `FieldPatches` global monkeypatches) is **deleted** for
121
- all migrated cases; the only remaining v2 coupling is in the explicitly force-blocked
122
- cases.
123
- 4. `bundle exec rspec` green in eco-helpers; gem suite still green.
124
- 5. No customer script edits required — verified against the downstream include-site
125
- inventory from Phase 0.
@@ -1,136 +0,0 @@
1
- # INVENTORY — Ooze → Native GraphQL Migration (Phase 0)
2
-
3
- Verified 2026-07-02 against actual code in `eco-helpers` (main code), `ecoportal-api-graphql`
4
- (gem), and `implementation/training` (downstream consumers). This is the **master schedule
5
- partition**: which cases can migrate now vs. are blocked on forces, and the BC surface that must
6
- keep working with **zero customer-script edits**.
7
-
8
- > **Scope note (Oscar, 2026-07-02):** this project currently builds the **native GraphQL classes
9
- > only**. We do NOT yet flip the `OozeSamples::*` names to delegate, and we do NOT remove shim
10
- > code. The delegation flip happens "long after we know everything works on the native samples."
11
-
12
- ---
13
-
14
- ## A. The ooze case inheritance tree (eco-helpers)
15
-
16
- Root path: `lib/eco/api/usecases/ooze_samples/`
17
-
18
- ```
19
- Eco::API::Common::Loaders::UseCase
20
- ├─ OozeSamples::OozeBaseCase (ooze_base_case.rb) include Helpers, Helpers::Rescuable
21
- │ └─ OozeSamples::OozeRunBaseCase (ooze_run_base_case.rb) single-ooze runner
22
- │ └─ OozeSamples::OozeUpdateCase (ooze_update_case.rb)
23
- │ └─ OozeSamples::OozeFromDocCase (ooze_from_doc_case.rb) + Word-doc parsing
24
- │ └─ OozeSamples::RegisterUpdateCase (register_update_case.rb) include Helpers::Creatable ← CUTOVER #1
25
- │ └─ OozeSamples::TargetOozesUpdateCase (target_oozes_update_case.rb) CSV target ids ← CUTOVER #2
26
- │ └─ OozeSamples::RegisterMigrationCase (register_migration_case.rb) include HelpersMigration
27
- └─ OozeSamples::RegisterExportCase (register_export_case.rb) standalone (NOT under OozeBaseCase)
28
- └─ OozeCases::ExportRegisterCase (ooze_cases/export_register_case.rb) include ExportableRegister
29
- ```
30
-
31
- ### Control-flow loop a native class must reproduce (RegisterUpdateCase)
32
-
33
- - `main(session, options, usecase, mode: :legacy)` → init KPIs → `:legacy` runs
34
- `with_each_entry { process_ooze(&block) }`; `:delegate` yields for a custom loop → log KPIs.
35
- - `with_each_entry` → `batched_search_results` yields page batches → per page: dedup check →
36
- `ooze(id)` load → yield to block → `update_oozes` (batch save).
37
- - `batched_search_results` → `apiv2.registers.search(register_id, search_options) { ... }`,
38
- batch-size chunking.
39
- - `search_options` → sort=created_at asc, `conf_search` (→ `search` hook), `conf_filters`
40
- (→ `filters` hook).
41
- - KPI counters: `total_search_oozes`, `retrieved_oozes`, `dupped_search_oozes`, `updated_oozes`,
42
- `failed_update_oozes`, `created_oozes`, `ooze_create_attempts`.
43
- - Dry-run: `results_preview` (confirm total, 10s timeout); `display_patch` / `backup_patch!` in base.
44
- - Internal batch queue: `enqueue` / `queue_shift` / `queue_get` (duck-types v2 Page / PageStage /
45
- anything responding to `dirty?` + `as_update`).
46
-
47
- `TargetOozesUpdateCase` overrides only `with_each_entry` (reads target ids from CSV column 1+,
48
- batches by size) — everything else inherited.
49
-
50
- **Native counterpart already has a head start:** eco-helpers
51
- `lib/eco/api/usecases/graphql/samples/pages/page/base.rb` already implements a **native GraphQL
52
- loop** (`process` → `init_kpis` → `each_page` → `process_page` → `log_kpis`, plus `update_page`
53
- with a simulate guard and register-scoped `search_conf`). The native register case builds on this
54
- `Pages::Page::Base`, NOT on a v2 loop.
55
-
56
- ---
57
-
58
- ## B. Helper modules — v2-coupled vs pure
59
-
60
- Root: `lib/eco/api/usecases/ooze_samples/helpers/` and `helpers_migration/`
61
-
62
- | Module | Path | Classification | Migration action |
63
- |---|---|---|---|
64
- | `Helpers::Shortcuts` | helpers/shortcuts.rb | **PURE** (string simplify/compare; one `obj.force` in a message) | Port ~verbatim to `graphql/helpers/pages/` |
65
- | `Helpers::Filters` | helpers/filters.rb | **PURE** (tag/date filters, time math) | Port ~verbatim |
66
- | `Helpers::Rescuable` | helpers/rescuable.rb | error-rescue wrapper | Port (thin) |
67
- | `Helpers::Creatable` | helpers/creatable.rb | **v2-coupled** (`apiv2.pages.get_new/create`; duck-types v2 Page) | GraphQL re-expression (native draft + create) |
68
- | `Helpers::OozeHandlers` | helpers/ooze_handlers.rb | **v2-coupled** (`merge_values` case-matches `V2::Page::Component::*`) | GraphQL-typed re-expression (per data-field type) |
69
- | `Helpers::ExportableOoze` | helpers/exportable_ooze.rb | v2-coupled (field value reads) | later (export cases) |
70
- | `Helpers::ExportableRegister` | helpers/exportable_register.rb | v2-coupled (ooze value aggregation) | later (export cases) |
71
- | `HelpersMigration::Copying` | helpers_migration/copying.rb | **v2-coupled** (field pairing/copy) | later (migration case) |
72
- | `HelpersMigration::TypedFieldsPairing` | helpers_migration/typed_fields_pairing.rb | **v2-coupled** (type+label pairing) | later (migration case) |
73
-
74
- **First-wave port:** `Shortcuts`, `Filters`, `Rescuable` (pure/thin) + a native `Creatable`.
75
-
76
- ---
77
-
78
- ## C. The compat shim being retired (NOT this session)
79
-
80
- `lib/eco/api/usecases/graphql/compat/ooze_redirect.rb` (+ `ooze_redirect/{dirty_array,field_patches,force_compat}.rb`).
81
-
82
- - `OozeRedirect.included(base)` → `FieldPatches.apply!` (global v2-class reopening + GraphQL field
83
- prepends), `base.include(GraphQLEnv)`, `base.prepend(Infrastructure)`,
84
- `+ ForceCompat::Infrastructure if force_support?` (currently `false`).
85
- - `Infrastructure` overrides (the leaf ops a native class implements directly instead):
86
- `api_v2`/`apiv2` → `graphql`; `stage(name)` → `StageView`; `with_fields(ooz, type:, label:)` →
87
- reads `ooz.components`; `dirty?` → `.dirty?` or captured submit/sign-off flags.
88
- - `FieldPatches` steps: v2 `===` dispatch lie; GraphQL BasePage `submit!`/`sign_off!` + pending
89
- flags; People `DirtyArray`; CrossReference `reference_ids`/`add`/`clear`; Select
90
- `options`/`select`/`deselect`/`values`.
91
-
92
- A native class needs NONE of these patches — it dispatches on GraphQL types directly.
93
-
94
- ---
95
-
96
- ## D. Forces partition (blocked until GraphQL forces endpoint is live)
97
-
98
- - **Base ooze cases (A) do NOT use forces** — `OozeBaseCase`, `RegisterUpdateCase`,
99
- `TargetOozesUpdateCase`, `RegisterMigrationCase`, `RegisterExportCase` are all force-free.
100
- → **All first-wave cutover cases are migratable now.**
101
- - **Forces live only in downstream training scripts** that subclass the register cases:
102
- | Script | Base | Force usage |
103
- |---|---|---|
104
- | `les_mills_force_update_case.rb` (Test_Les) | RegisterUpdateCase | `forces.get_by_name` → `force.custom_script =` |
105
- | `20231031_fix_options_case.rb` (FIXOPTIONS) | RegisterUpdateCase | `forces.each` → `force.custom_script =` |
106
- | `08102024_THL_RemoveLocTitle_case.rb` (REMOVELOCTITLEHAZ) | RegisterUpdateCase | `forces.get_by_name` → `custom_script =` |
107
- | `rename_field_case.rb` (AddFieldBinding) | RegisterUpdateCase | `forces.delete!` |
108
- | `attach_image_case.rb` (AttachImage) | TargetOozesUpdateCase | `forces.get_by_name` |
109
- - **Note:** the gem *does* ship forces write commands via the command bus
110
- (`addForce`/`editForce`/`addBinding`/…) and `OozeRedirect.force_support?` being `false` is
111
- stale/conservative (see memory `forces-via-workflow-commands`). But the ooze-case force *read*
112
- path (`target.forces.get_by_name`, `force.custom_script=`) is a different surface and its
113
- GraphQL end-to-end readiness is UNCONFIRMED. These scripts stay on the v2 path until confirmed.
114
-
115
- ---
116
-
117
- ## E. Downstream include-site inventory (BC surface)
118
-
119
- - Training repo `C:\ruby_scripts\implementation\training` **exists**; **273+ custom cases**.
120
- - **All are still APIv2-only** — none currently `include GraphQL::Compat::OozeRedirect` (the live
121
- TOOCS/CANS cutover scripts that DO use it are not in this training tree — locate them before any
122
- flip; not needed this session since we are not flipping).
123
- - Overrides seen across consumers (the hooks a native class must keep honoring):
124
- `process_ooze` (always), `search`, `filters`, `custom_processing`, plus script-local helpers
125
- (`with_target_stage`, `target_stage`, `with_target_field`, `with_target_force`, etc.).
126
-
127
- ---
128
-
129
- ## F. Migration order (schedule)
130
-
131
- 1. **Now (native only):** port pure helpers (`Shortcuts`, `Filters`, `Rescuable`) + native
132
- `Creatable`; native register base case on top of `Pages::Page::Base`; specs. **No flip.**
133
- 2. Native `RegisterUpdateCase` + `TargetOozesUpdateCase` counterparts; A/B parity harness.
134
- 3. (Later) flip old names → delegate, per-case, parity-gated; remove shim slices.
135
- 4. (Blocked) force-using cases — pending GraphQL force read/write end-to-end confirmation.
136
- 5. (Later) export + migration cases (`ExportableRegister`, `Copying`, `TypedFieldsPairing`).