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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +87 -0
- data/lib/ecoportal/api/common/graphql/client.rb +0 -2
- data/lib/ecoportal/api/common/graphql/http_client.rb +6 -0
- data/lib/ecoportal/api/graphql/base/ai_summary_version.rb +17 -17
- data/lib/ecoportal/api/graphql/base/file_container.rb +14 -14
- data/lib/ecoportal/api/graphql/base/location_classification_type.rb +15 -15
- data/lib/ecoportal/api/graphql/base/location_structure.rb +27 -27
- data/lib/ecoportal/api/graphql/base/organization.rb +15 -15
- data/lib/ecoportal/api/graphql/base/page/task.rb +24 -0
- data/lib/ecoportal/api/graphql/base/page.rb +17 -16
- data/lib/ecoportal/api/graphql/base/template.rb +35 -0
- data/lib/ecoportal/api/graphql/base.rb +37 -35
- data/lib/ecoportal/api/graphql/builder/contractor_entity.rb +41 -41
- data/lib/ecoportal/api/graphql/compat/response.rb +35 -35
- data/lib/ecoportal/api/graphql/connection/action.rb +11 -11
- data/lib/ecoportal/api/graphql/connection/action_category.rb +11 -11
- data/lib/ecoportal/api/graphql/connection/contractor_entity.rb +11 -11
- data/lib/ecoportal/api/graphql/connection/page.rb +11 -11
- data/lib/ecoportal/api/graphql/connection/person_member.rb +11 -11
- data/lib/ecoportal/api/graphql/connection/preview_page.rb +11 -11
- data/lib/ecoportal/api/graphql/connection.rb +17 -17
- data/lib/ecoportal/api/graphql/file_upload/client.rb +21 -10
- data/lib/ecoportal/api/graphql/fragment/field_configuration.rb +38 -0
- data/lib/ecoportal/api/graphql/fragment/force.rb +14 -10
- data/lib/ecoportal/api/graphql/fragment/location_node.rb +26 -26
- data/lib/ecoportal/api/graphql/fragment/page_task.rb +39 -0
- data/lib/ecoportal/api/graphql/fragment/template.rb +51 -0
- data/lib/ecoportal/api/graphql/fragment.rb +3 -0
- data/lib/ecoportal/api/graphql/input/contractor_entity.rb +14 -14
- data/lib/ecoportal/api/graphql/input/preset_view/update.rb +16 -16
- data/lib/ecoportal/api/graphql/input/workflow_command/add_stage.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +21 -21
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_page.rb +28 -28
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_page_creator_permissions.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +23 -23
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/date.rb +20 -20
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/image_gallery.rb +20 -20
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/people.rb +24 -24
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/plain_text.rb +20 -20
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/rich_text.rb +20 -20
- data/lib/ecoportal/api/graphql/input/workflow_command/field_config/select.rb +20 -20
- data/lib/ecoportal/api/graphql/input/workflow_command/move_field.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/reorder_forces.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command/reorder_section.rb +18 -18
- data/lib/ecoportal/api/graphql/input/workflow_command.rb +251 -251
- data/lib/ecoportal/api/graphql/input.rb +24 -24
- data/lib/ecoportal/api/graphql/logic/connection.rb +34 -34
- data/lib/ecoportal/api/graphql/model/page/task.rb +16 -0
- data/lib/ecoportal/api/graphql/model/page.rb +16 -15
- data/lib/ecoportal/api/graphql/model/person_member.rb +15 -15
- data/lib/ecoportal/api/graphql/model/template.rb +15 -0
- data/lib/ecoportal/api/graphql/model.rb +32 -30
- data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +45 -45
- data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/contractor_entity.rb +14 -14
- data/lib/ecoportal/api/graphql/mutation/page/approve_review_task.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/page/batch_update_review_task.rb +38 -40
- data/lib/ecoportal/api/graphql/mutation/page/create_draft.rb +38 -40
- data/lib/ecoportal/api/graphql/mutation/page/delete_draft.rb +38 -40
- data/lib/ecoportal/api/graphql/mutation/page/execute_force_commands.rb +7 -7
- data/lib/ecoportal/api/graphql/mutation/page/execute_workflow_commands.rb +8 -7
- data/lib/ecoportal/api/graphql/mutation/page/publish_draft.rb +38 -40
- data/lib/ecoportal/api/graphql/mutation/page/reject_review_task.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/page/restart_review_task.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/page/undo_review_task.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/preset_view/destroy.rb +34 -35
- data/lib/ecoportal/api/graphql/mutation/register/destroy.rb +35 -35
- data/lib/ecoportal/api/graphql/mutation/smart_fill/generate.rb +36 -36
- data/lib/ecoportal/api/graphql/mutation/smart_fill/submit_feedback.rb +40 -40
- data/lib/ecoportal/api/graphql/mutation/smart_fill.rb +13 -13
- data/lib/ecoportal/api/graphql/mutation/template/create_related_page.rb +46 -46
- data/lib/ecoportal/api/graphql/mutation/template/destroy_related_page.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation/template/update_information.rb +1 -1
- data/lib/ecoportal/api/graphql/mutation.rb +20 -20
- data/lib/ecoportal/api/graphql/payload/contractor_entity.rb +14 -14
- data/lib/ecoportal/api/graphql/payload/ok_payload.rb +36 -21
- data/lib/ecoportal/api/graphql/payload/page/draft.rb +26 -13
- data/lib/ecoportal/api/graphql/payload/page/review_task.rb +13 -13
- data/lib/ecoportal/api/graphql/payload/page/review_task_batch.rb +23 -0
- data/lib/ecoportal/api/graphql/payload/page.rb +20 -19
- data/lib/ecoportal/api/graphql/payload/preset_view.rb +15 -11
- data/lib/ecoportal/api/graphql/payload/register.rb +15 -11
- data/lib/ecoportal/api/graphql/payload/template/create_related_page.rb +1 -1
- data/lib/ecoportal/api/graphql/payload/template/destroy_related_page.rb +1 -1
- data/lib/ecoportal/api/graphql/payload/template/update_information.rb +1 -1
- data/lib/ecoportal/api/graphql/payload.rb +23 -23
- data/lib/ecoportal/api/graphql/query/location_structures.rb +57 -57
- data/lib/ecoportal/api/graphql/query/page.rb +45 -45
- data/lib/ecoportal/api/graphql/query/page_with_forces.rb +9 -3
- data/lib/ecoportal/api/graphql/query/pages_workflow_commands.rb +9 -3
- data/lib/ecoportal/api/graphql/query/register_preset_views.rb +78 -78
- data/lib/ecoportal/api/graphql/query.rb +27 -27
- data/lib/ecoportal/api/graphql.rb +9 -5
- data/lib/ecoportal/api/graphql_version.rb +1 -1
- metadata +9 -180
- data/.ai-assistance/bridge/CLAUDE.md +0 -338
- data/.ai-assistance/bridge/archive/.gitkeep +0 -0
- data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.inbox.md +0 -29
- data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.outbox.md +0 -18
- data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.inbox.md +0 -42
- data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.outbox.md +0 -115
- data/.ai-assistance/bridge/context/gemini-review-prompt.txt +0 -48
- data/.ai-assistance/bridge/context/gemini-review-response.md +0 -104
- data/.ai-assistance/bridge/context/project.md +0 -42
- data/.ai-assistance/bridge/inbox/.gitkeep +0 -0
- data/.ai-assistance/bridge/outbox/.gitkeep +0 -0
- data/.ai-assistance/bridge/outbox/request-for-standards-discovery.md +0 -48
- data/.ai-assistance/bridge/queue/.gitkeep +0 -1
- data/.ai-assistance/capabilities/CLAUDE.md +0 -27
- data/.ai-assistance/capabilities/assumptions-log.md +0 -80
- data/.ai-assistance/capabilities/code.md +0 -47
- data/.ai-assistance/capabilities/connectors.md +0 -37
- data/.ai-assistance/capabilities/cowork.md +0 -55
- data/.ai-assistance/code/OVERVIEW.md +0 -155
- data/.ai-assistance/code/data_fields.md +0 -242
- data/.ai-assistance/code/dependencies.md +0 -151
- data/.ai-assistance/code/diff_as_input.md +0 -234
- data/.ai-assistance/code/diff_pairing_engine.md +0 -243
- data/.ai-assistance/code/diff_service_deep_dive.md +0 -192
- data/.ai-assistance/code/ecoPortal_architecture/00_overview_and_index.md +0 -55
- data/.ai-assistance/code/ecoPortal_architecture/01_terminology_dictionary.md +0 -181
- data/.ai-assistance/code/ecoPortal_architecture/02_data_model.md +0 -192
- data/.ai-assistance/code/ecoPortal_architecture/03_api_layers.md +0 -147
- data/.ai-assistance/code/ecoPortal_architecture/04_graphql_queries_mutations.md +0 -277
- data/.ai-assistance/code/ecoPortal_architecture/05_page_workflows.md +0 -200
- data/.ai-assistance/code/ecoPortal_architecture/06_search_and_filters.md +0 -228
- data/.ai-assistance/code/ecoPortal_architecture/07_data_fields.md +0 -197
- data/.ai-assistance/code/ecoPortal_architecture/08_stages_sections.md +0 -243
- data/.ai-assistance/code/ecoPortal_architecture/09_people_contractors_locations.md +0 -196
- data/.ai-assistance/code/ecoPortal_architecture/10_forces_workflow_builder.md +0 -132
- data/.ai-assistance/code/ecoPortal_architecture/11_integration_gems.md +0 -187
- data/.ai-assistance/code/ecoPortal_architecture/12_ai_documentation_sources_gaps.md +0 -236
- data/.ai-assistance/code/ecoPortal_architecture/13_ai_infrastructure.md +0 -183
- data/.ai-assistance/code/ecoportal_schema_reference.md +0 -240
- data/.ai-assistance/code/filter_contract_matrix.md +0 -177
- data/.ai-assistance/code/graphql_domain_knowledge.md +0 -240
- data/.ai-assistance/code/refactoring/datafield-readwrite-shape-asymmetry.md +0 -71
- data/.ai-assistance/code/refactoring/opportunities.md +0 -251
- data/.ai-assistance/code/schema_analysis.md +0 -321
- data/.ai-assistance/code/search_filters.md +0 -868
- data/.ai-assistance/code/spec_coverage.md +0 -73
- data/.ai-assistance/code/template_diff_pairing_domain.md +0 -175
- data/.ai-assistance/code/workflow-command-guide.md +0 -466
- data/.ai-assistance/code/workflow-space.md +0 -353
- data/.ai-assistance/conventions/CLAUDE.md +0 -30
- data/.ai-assistance/conventions/code-working-tree-protocol.md +0 -199
- data/.ai-assistance/conventions/gitignore-rules.md +0 -42
- data/.ai-assistance/conventions/permission-guidance.md +0 -120
- data/.ai-assistance/integrations/README.md +0 -70
- data/.ai-assistance/integrations/gitkraken-mcp.md +0 -107
- data/.ai-assistance/integrations/gitlab-mcp.md +0 -123
- data/.ai-assistance/integrations/local-git.md +0 -60
- data/.ai-assistance/local_paths.example.md +0 -17
- data/.ai-assistance/projects/TODO.md +0 -118
- data/.ai-assistance/projects/api-v2-to-graphql-migration/DECISIONS.md +0 -168
- data/.ai-assistance/projects/api-v2-to-graphql-migration/INTENT.md +0 -60
- data/.ai-assistance/projects/api-v2-to-graphql-migration/TODO.md +0 -267
- data/.ai-assistance/projects/api-v2-to-graphql-migration/UPSTREAM.md +0 -53
- data/.ai-assistance/projects/api-v2-to-graphql-migration/notes/csv-template-pipeline-design.md +0 -102
- data/.ai-assistance/projects/api-v2-to-graphql-migration/notes/cutover-usecase-gap-audit.md +0 -139
- data/.ai-assistance/projects/compat-layer-audit/COMPAT_AUDIT.md +0 -244
- data/.ai-assistance/projects/dynamic-model-generation/INTENT.md +0 -93
- data/.ai-assistance/projects/eco-helpers-compat/INTENT.md +0 -244
- data/.ai-assistance/projects/eco-helpers-compat/MIGRATION_GUIDE.md +0 -266
- data/.ai-assistance/projects/eco-helpers-compat/TODO.md +0 -86
- data/.ai-assistance/projects/ecoportal-api-v2-doublemodel-review/INTENT.md +0 -101
- data/.ai-assistance/projects/graphql-agent/GAP_ANALYSIS.md +0 -177
- data/.ai-assistance/projects/ooze-graphql-native-migration/DECISIONS.md +0 -161
- data/.ai-assistance/projects/ooze-graphql-native-migration/INTENT.md +0 -125
- data/.ai-assistance/projects/ooze-graphql-native-migration/INVENTORY.md +0 -136
- data/.ai-assistance/projects/ooze-graphql-native-migration/RISKS.md +0 -126
- data/.ai-assistance/projects/ooze-graphql-native-migration/TODO.md +0 -261
- data/.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-06-30-cutover-workflow-deep-review.md +0 -122
- data/.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-07-01-forces-via-workflow-commands-miss-rca.md +0 -148
- data/.ai-assistance/projects/page-model/DECISIONS.md +0 -245
- data/.ai-assistance/projects/page-model/TODO.md +0 -190
- data/.ai-assistance/projects/qa-services-delivery/DECISIONS.md +0 -93
- data/.ai-assistance/projects/qa-services-delivery/INTENT.md +0 -76
- data/.ai-assistance/projects/qa-services-delivery/PHASE3-SCOPE.md +0 -115
- data/.ai-assistance/projects/qa-services-delivery/ROADMAP.md +0 -99
- data/.ai-assistance/projects/qa-services-delivery/TODO.md +0 -81
- data/.ai-assistance/projects/search-filter-builder/INTENT.md +0 -107
- data/.ai-assistance/projects/search-filter-builder/TODO.md +0 -131
- data/.ai-assistance/projects/template-automatic-build-maintenance/INTENT.md +0 -87
- data/.ai-assistance/projects/template-automatic-build-maintenance/TODO.md +0 -108
- data/.ai-assistance/projects/template-diff-deploy/INTENT.md +0 -12
- data/.ai-assistance/projects/template-diff-deploy/TODO.md +0 -9
- data/.ai-assistance/projects/template-maintenance/DESIGN.md +0 -134
- data/.ai-assistance/projects/template-maintenance/PHASE0-FINDINGS.md +0 -93
- data/.ai-assistance/projects/template-maintenance/README.md +0 -14
- data/.ai-assistance/projects/template-model-logic/CATEGORY_CATALOG.md +0 -236
- data/.ai-assistance/projects/template-model-logic/CLASSIFICATION_SPIKE.md +0 -243
- data/.ai-assistance/projects/template-model-logic/DESIGN_NOTE.md +0 -154
- data/.ai-assistance/projects/workflow-space/TODO.md +0 -213
- data/.ai-assistance/reinstall-claude-desktop-windows.md +0 -136
- data/.ai-assistance/scripts/CLAUDE.md +0 -150
- data/.ai-assistance/scripts/bridge-inbox-check.sh +0 -75
- data/.ai-assistance/scripts/bridge-init.sh +0 -86
- data/.ai-assistance/scripts/bridge-status.sh +0 -44
- data/.ai-assistance/scripts/capabilities-check.ts +0 -104
- data/.ai-assistance/scripts/check-outbox.sh +0 -43
- data/.ai-assistance/scripts/dep_graph.rb +0 -91
- data/.ai-assistance/scripts/lock-acquire.sh +0 -103
- data/.ai-assistance/scripts/lock-multi.sh +0 -124
- data/.ai-assistance/scripts/lock-queue.sh +0 -94
- data/.ai-assistance/scripts/setup-mcps.test.ts +0 -188
- data/.ai-assistance/scripts/setup-mcps.ts +0 -234
- data/.ai-assistance/scripts/task-complete.ts +0 -74
- data/.ai-assistance/scripts/task-create.ts +0 -75
- data/.ai-assistance/scripts/task-read.ts +0 -125
- data/.ai-assistance/scripts/token-logger.js +0 -220
- data/.ai-assistance/scripts/token-report.ts +0 -158
- data/.ai-assistance/scripts/token-session-start.js +0 -66
- data/.ai-assistance/skills/ai-instructions/SKILL.md +0 -48
- data/.ai-assistance/skills/code-specs/SKILL.md +0 -69
- data/.ai-assistance/skills/corporate-policies/SKILL.md +0 -201
- data/.ai-assistance/skills/dep-graph/SKILL.md +0 -139
- data/.ai-assistance/skills/ep-ai-manager/SKILL.md +0 -417
- data/.ai-assistance/skills/gemini-assist/SKILL.md +0 -63
- data/.ai-assistance/skills/gemini-assist/gemini-mcp-server.js +0 -205
- data/.ai-assistance/skills/gemini-assist/gemini_ask.py +0 -1
- data/.ai-assistance/skills/gemini-assist/gemini_ask.rb +0 -240
- data/.ai-assistance/skills/gemini-assist/prompts/cycle_end_review.txt +0 -25
- data/.ai-assistance/skills/graphql-schema-analysis/SKILL.md +0 -261
- data/.ai-assistance/skills/procedural-memory/SKILL.md +0 -319
- data/.ai-assistance/skills/project-cycle/SKILL.md +0 -177
- data/.ai-assistance/skills/project-self-docs/SKILL.md +0 -181
- data/.ai-assistance/skills/project-self-docs/scripts/self_docs_scan.py +0 -378
- data/.ai-assistance/skills/refactor/SKILL.md +0 -62
- data/.ai-assistance/skills/rubocop/SKILL.md +0 -93
- data/.ai-assistance/skills/ruby-scripting/SKILL.md +0 -215
- data/.ai-assistance/skills/spec-generation/SKILL.md +0 -72
- data/.ai-assistance/standards-version.json +0 -22
- data/.ai-assistance/token-budget.json +0 -32
- data/.ai-assistance/version.json +0 -39
- data/.claude/settings.json +0 -150
- data/.env.example +0 -18
- data/.gitattributes +0 -15
- data/.gitignore +0 -37
- data/.gitlab-ci.yml +0 -45
- data/.markdownlint.json +0 -4
- data/.rspec +0 -3
- data/.rubocop.yml +0 -121
- data/.ruby-version +0 -1
- data/.yardopts +0 -10
- data/CLAUDE.md +0 -243
- data/Gemfile +0 -30
- data/Rakefile +0 -90
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/bin/setup.ps1 +0 -6
- data/docs/self-docs/ARCHITECTURE.md +0 -88
- data/docs/self-docs/CHANGES.jsonl +0 -12
- data/docs/self-docs/COMPLIANCE.md +0 -79
- data/docs/self-docs/CONVENTIONS.md +0 -74
- data/docs/self-docs/INTEGRATIONS.md +0 -65
- data/docs/self-docs/OPERATIONS.md +0 -76
- data/docs/self-docs/OVERVIEW.md +0 -64
- data/docs/self-docs/STATUS.md +0 -73
- data/docs/self-docs/self-docs-index.json +0 -51
- data/docs/worklog.md +0 -977
- data/ecoportal-api-graphql.gemspec +0 -40
- data/scripts/auto-worker-scheduler.sh +0 -386
- data/tests/actions_get.rb +0 -7
- data/tests/contractor_entities_get.rb +0 -20
- data/tests/contractor_entity_create.rb +0 -19
- data/tests/contractor_entity_udpate.rb +0 -20
- data/tests/dump_page_model.rb +0 -74
- data/tests/dump_template_model.rb +0 -90
- data/tests/loc_structure_get.rb +0 -10
- data/tests/loc_structure_update.rb +0 -51
- data/tests/loc_structures_get.rb +0 -15
- data/tests/local_libs.rb +0 -20
- 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`).
|