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,73 +0,0 @@
|
|
|
1
|
-
# Spec Coverage Map
|
|
2
|
-
|
|
3
|
-
*Last updated: 2026-06-07*
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Areas WITH specs (117 examples total)
|
|
8
|
-
|
|
9
|
-
| Spec file | What it covers |
|
|
10
|
-
|---|---|
|
|
11
|
-
| `common/graphql/model/as_input_spec.rb` | `AsInput#as_input`, `Logic::Input.from_model`, `ContractorEntity::Update.from_model` |
|
|
12
|
-
| `common/graphql/model/diff_service_spec.rb` | `DiffService#diff` — no-change, single prop, nested, root! exclusion |
|
|
13
|
-
| `base/page/data_field_spec.rb` | `DataField.from_doc` dispatch, dirty tracking, `as_input` for PlainText/RichText/Select/People/Checklist, `Collection` get_by_type/get_by_name/dirty_inputs |
|
|
14
|
-
| `concerns/fragment_definitions_spec.rb` | `FragmentDefinitions.assemble`, `register_namespace` cross-namespace discovery, `Fragment::Pages` integration |
|
|
15
|
-
| `input/page/update_spec.rb` | `Input::Page::Update.from_model` — no-change nil, patchVer injection, publish flag, clientMutationId |
|
|
16
|
-
| `input/search_conf_spec.rb` | `SearchConf` builder — all filter types, sort, query, `#with` parametrization, `as_json` |
|
|
17
|
-
| `logic/assemble_fragments_spec.rb` | `BaseQuery#assemble_fragments` — single, recursive (PageFields→LocationNode), cycle safety, deduplication |
|
|
18
|
-
| `model/page_union_spec.rb` | `Model::PageUnion.new` — `__typename` dispatch to Basic/Phased/fallback, opts forwarded |
|
|
19
|
-
| `api_spec.rb` | Version constant smoke test |
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Areas WITHOUT specs (by design or deferred)
|
|
24
|
-
|
|
25
|
-
### Query / Mutation / Payload / Builder classes
|
|
26
|
-
No unit specs. These classes primarily wire DSL blocks to HTTP + response wrapping —
|
|
27
|
-
meaningful tests require a live or stubbed GraphQL server. Integration testing via
|
|
28
|
-
`tests/` scripts (manual) is the current approach.
|
|
29
|
-
|
|
30
|
-
Includes: `Query::Page`, `Query::Pages`, `Query::Templates`, `Query::RegisterPreviewPages`,
|
|
31
|
-
`Query::PageDelta`, all `Mutation::Page::*`, all `Payload::Page::*`, `Builder::Page`.
|
|
32
|
-
|
|
33
|
-
**Gap severity: Low** — the classes are thin wrappers; bugs show up on integration.
|
|
34
|
-
If stubs become practical, priority order: `Query::Page`, `Query::Pages`.
|
|
35
|
-
|
|
36
|
-
### Compat layer
|
|
37
|
-
No unit specs for `Compat::Pages`, `Compat::Registers`, `Compat::StageCollection`,
|
|
38
|
-
`Compat::SearchResults`. These require either a live GraphQL connection or deep mocking.
|
|
39
|
-
|
|
40
|
-
**Gap severity: Medium** — integration testing with the end-script repo (pending access)
|
|
41
|
-
will cover this.
|
|
42
|
-
|
|
43
|
-
### Model classes (stubs and pass-through)
|
|
44
|
-
`Base::Page::Basic`, `Base::Page::Phased`, `Model::Page::Basic`, `Model::Page::Phased`,
|
|
45
|
-
`Base::PreviewPage`, `Base::DeltaResult`, `Base::Page::DataField::TagField/Geo/Gauge/Date/Number`
|
|
46
|
-
— these are mostly DSL declarations with no business logic. Not worth unit-testing.
|
|
47
|
-
|
|
48
|
-
### Fragment definitions (GRAPHQL strings)
|
|
49
|
-
`Fragment::PageFields`, `BasicPageFields`, `PhasedPageFields` — assembly is tested via
|
|
50
|
-
`assemble_fragments_spec.rb`. Individual fragment content is validated in integration.
|
|
51
|
-
|
|
52
|
-
### Input stubs
|
|
53
|
-
`Input::DeltaInput`, `Input::Page::Archive`, `Input::Page::Unarchive`,
|
|
54
|
-
`Input::Page::BuildFromTemplate`, `Input::Page::CreateFromTemplate` — simple passthrough
|
|
55
|
-
classes. Worth adding if any logic is added.
|
|
56
|
-
|
|
57
|
-
### Concerns
|
|
58
|
-
`Concerns::DataFieldAccess`, `Concerns::PageCompat`, `Concerns::PhasedPageCompat` —
|
|
59
|
-
tested indirectly via `data_field_spec.rb` and `page_union_spec.rb`.
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
## Recommended next specs (priority order)
|
|
64
|
-
|
|
65
|
-
1. **`Input::Page::Update.from_model` with `dataFields`** — now that field changes are
|
|
66
|
-
included, add a test that dirty fields appear in `dataFields.updates`.
|
|
67
|
-
File: extend `spec/ecoportal/api/graphql/input/page/update_spec.rb`
|
|
68
|
-
|
|
69
|
-
2. **`StageCollection`** — `stages[name]`, `stages.get_by_name`, `stages.ordered`.
|
|
70
|
-
File: `spec/ecoportal/api/graphql/compat/stage_collection_spec.rb`
|
|
71
|
-
|
|
72
|
-
3. **`SearchConf` filter translation in Registers** — v2 `date_filter` lbound→gte.
|
|
73
|
-
File: `spec/ecoportal/api/graphql/compat/registers_spec.rb` (filter translation only)
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
# Template Lifecycle, Diffing, Pairing & Deployment — Domain Knowledge
|
|
2
|
-
|
|
3
|
-
**Status:** authoritative domain capture (harvestable by ep-ai-standards). Sourced from Oscar
|
|
4
|
-
(platform maintainer) 2026-07-03, with schema/code facts verified inline. This is the single
|
|
5
|
-
reference for the template diff/deploy/sync problem space — do not re-derive it from scratch.
|
|
6
|
-
|
|
7
|
-
Related: `graphql_domain_knowledge.md` (§ genome), `.ai-assistance/projects/template-diff-deploy/`,
|
|
8
|
-
`.ai-assistance/projects/template-maintenance/`, `.ai-assistance/projects/qa-services-delivery/`.
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## 1. Why this matters
|
|
13
|
-
|
|
14
|
-
Most quality work in Services Delivery revolves around **template changes** and the **tech-script
|
|
15
|
-
fixes** applied to a register's pages after a **failed QA on a published template** produced wrong
|
|
16
|
-
pages. Templates are the epicenter of admin + troubleshooting automation — **not a QA-only concern**.
|
|
17
|
-
|
|
18
|
-
## 2. The UAT→PROD template lifecycle and its failure modes
|
|
19
|
-
|
|
20
|
-
Jira tickets (service **xor** support) raise actions to **change templates** (most commonly). Those
|
|
21
|
-
changes are either:
|
|
22
|
-
- applied **directly to the PROD template** (or a DEV template that becomes PROD on the org launch date), or
|
|
23
|
-
- applied first to the **UAT** site template, then replicated to PROD after customer approval.
|
|
24
|
-
|
|
25
|
-
Because the whole process is **manual**, it regresses in two directions:
|
|
26
|
-
- **Regression A (lost changes):** someone unpublishes/replaces the PROD template with a **YAML backup
|
|
27
|
-
copy of UAT**. Any PROD-only changes not present in UAT are **silently lost**.
|
|
28
|
-
- **Regression B (premature release):** UAT already carried changes **not yet approved for release**;
|
|
29
|
-
replacing PROD with UAT **releases them**, and the customer becomes unhappy.
|
|
30
|
-
|
|
31
|
-
Current mitigation (costly): hand-account **every** UAT change in detail; the **same staff member**
|
|
32
|
-
who changed UAT re-does those changes in PROD. This introduces its own errors — PROD may differ from
|
|
33
|
-
UAT, or the person forgets some changes. Goal: make this **smooth, effective, efficient** — no extra
|
|
34
|
-
comms, no back-and-forth, no trust loss, no rectifying tech-scripts.
|
|
35
|
-
|
|
36
|
-
## 3. The core obstacle — no stable identity (MongoDB)
|
|
37
|
-
|
|
38
|
-
MongoDB assigns a **distinct ID to every object in the nested page hierarchy**, and IDs are **not
|
|
39
|
-
shared** across: template vs its child pages, page vs page, UAT template vs PROD template. Nothing
|
|
40
|
-
has the same ID as its counterpart anywhere.
|
|
41
|
-
|
|
42
|
-
Consequences seen platform-wide:
|
|
43
|
-
- Customer integrations must **fetch the page model first** just to learn sub-object IDs (e.g.
|
|
44
|
-
`dataField` ids) before building a patch payload.
|
|
45
|
-
- The **field ref** (a truncated sha of the label name) is used as a pseudo-key in analytics — it's
|
|
46
|
-
unstable; the **Field ID project** exists to add certainty here.
|
|
47
|
-
|
|
48
|
-
## 4. THE key distinction — self-version diff vs cross-object diff
|
|
49
|
-
|
|
50
|
-
| | IDs | Pairing needed? | Difficulty |
|
|
51
|
-
|---|---|---|---|
|
|
52
|
-
| **Self-version** (same object, vN vs vN+1) | **retained** | none — match by id | trivial ✅ **built** |
|
|
53
|
-
| **Cross-object** (UAT↔PROD, page↔template) | **different** | yes — equivalence | hard |
|
|
54
|
-
|
|
55
|
-
- **Self-version** captures "what did this ticket change to the UAT template" exactly, as long as the
|
|
56
|
-
original snapshot was retained. Implemented: `Ecoportal::API::GraphQL::Diff::VersionDiff` (gem).
|
|
57
|
-
- **Cross-object** is the hard one: to diff, you must **pair counterpart objects** across two id-spaces,
|
|
58
|
-
translate to a common id-space in memory, diff, then map back. Only a fully-mapped copy can be diffed.
|
|
59
|
-
|
|
60
|
-
## 5. The genome signature — VERIFIED facts + why it can't be the sole key
|
|
61
|
-
|
|
62
|
-
**What it is:** an identifier introduced by the original ecoPortal developer (~2015/16) intended to
|
|
63
|
-
pair objects across a template and its child pages, and across YAML backup→restore. The genome is
|
|
64
|
-
**inherited** template-(sub)object → child-page-(sub)object, and copied on restore. It **grows** each
|
|
65
|
-
time it is restored or a child page is created (a related backend commit had to be amended for this).
|
|
66
|
-
|
|
67
|
-
**⚠️ VERIFIED 2026-07-03 (corrects the older "not exposed" claim in `graphql_domain_knowledge.md`):**
|
|
68
|
-
The live NewEp GraphQL schema (`.ai-assistance/tmp/20260605T101224_live_ep_graphql_schema.graphql.json`)
|
|
69
|
-
**DOES expose `genomeSignature: String`** on the **`DataFieldsInterface`** and on **every concrete
|
|
70
|
-
data-field type** (PlainText, RichText, Date, Number, Gauge, People, Select, Checklist, TagField, Geo,
|
|
71
|
-
Signature, ContractorEntities, CrossReference, ImageGallery, File, Mailbox, ActionsList, Law,
|
|
72
|
-
AiSummary, TableField, Chart, FrequencyRateChart, EmbeddedStructure, PageAction). APIv2 also exposed it
|
|
73
|
-
(developer "Rien" eventually exposed everything). It is **on data fields, not on sections/stages/pages**
|
|
74
|
-
(per the introspection). **Our gem does NOT yet request it** — no fragment/model field — so to use it
|
|
75
|
-
we add `genomeSignature` to the data-field fragment + `Base::Page::DataField`. It is **not indexed** in
|
|
76
|
-
Elasticsearch.
|
|
77
|
-
|
|
78
|
-
**Why genome is NOT an unarguable pairing key (Oscar's failure modes — design constraints):**
|
|
79
|
-
- (a) pairing was **manual**, with no platform support;
|
|
80
|
-
- (b) **new features** (new field types, linked-field configs, …) were never added to the genome solution;
|
|
81
|
-
- (c) it's **wrong for select options** — an option's key is the **value (primary)** or **name
|
|
82
|
-
(auxiliary)**, never the genome;
|
|
83
|
-
- (d) it wrongly **syncs checklist fields** from the template (shouldn't happen);
|
|
84
|
-
- (e) the premise "genome is always an unarguable pairing key" is **false**: a configurator may
|
|
85
|
-
**re-use** a field for something else then add a same-name/type field (realising the mistake); a
|
|
86
|
-
structural/conceptual **revamp** may carry same-label/type fields re-used for a different purpose; or
|
|
87
|
-
a field is **re-purposed** keeping its genome (e.g. `Date logged:` → `Date of sign-off:`);
|
|
88
|
-
- (f) **data-loss accounting** is incomplete and under-documented.
|
|
89
|
-
|
|
90
|
-
The abandoned backend solution built on genome: `app/services/migration/*`, notably
|
|
91
|
-
`Migration::GenomeKindship` — synced children pages to their parent template via genome pairing.
|
|
92
|
-
Abandoned for the reasons above, but its **founding principle is valid** (see §6).
|
|
93
|
-
|
|
94
|
-
## 6. The load-bearing simplifying principle (valid)
|
|
95
|
-
|
|
96
|
-
**Sections/stages are scaffolding, NOT data containers.** Customer data lives in the **data-fields**
|
|
97
|
-
(+ core page properties: old tags → now `location_ids` + `custom_tags`, `created_at`, …). Therefore
|
|
98
|
-
**restructuring is tractable as long as you can pair the customer data between the original-stage
|
|
99
|
-
field and the end-state field.** This dramatically shrinks the problem: **pair fields precisely; treat
|
|
100
|
-
structure as context.** That `genomeSignature` lives on data-fields aligns exactly with this.
|
|
101
|
-
|
|
102
|
-
Proven in practice by the migration-scripts framework (`doc/scripts/v*`): field-pairing via `FIELDS_MAP`
|
|
103
|
-
(`20231129_stolt_tra_migrate.rb`, `20240125_gns_con_migrate.rb`); later, due to page variability in
|
|
104
|
-
some registers, a different approach — **re-import via the current template's import spreadsheet**
|
|
105
|
-
(customer fills a data CSV extract) + a final tech-script for non-importable fields
|
|
106
|
-
(`20251202_luna_park_migration.rb`, `20260615_resene_copy_files.rb`).
|
|
107
|
-
|
|
108
|
-
## 7. Pairing = equivalence matching (the reframe — CONFIRMED by Oscar 2026-07-03)
|
|
109
|
-
|
|
110
|
-
Stable identity across independent Mongo objects does not exist, so **reframe from identity to
|
|
111
|
-
EQUIVALENCE** — a **record-linkage / entity-resolution** problem:
|
|
112
|
-
|
|
113
|
-
- Combine **multiple weak signals** into a **confidence score**:
|
|
114
|
-
`genomeSignature` (strong, now available on data fields), **type + label** (already implemented:
|
|
115
|
-
eco-helpers `HelpersMigration::TypedFieldsPairing` / `copying.rb`), **section heading + position**,
|
|
116
|
-
**select options-by-value**, structural context.
|
|
117
|
-
- **Auto-accept** high confidence; **route ambiguous / low-confidence to a HUMAN**; the assistant asks
|
|
118
|
-
the user to resolve unmatched cases and adjudicate doubtful pairings.
|
|
119
|
-
- **Persist every decision to a LEARNING LEDGER** (confirmed a first-class artifact): the pairings +
|
|
120
|
-
the log of *how* each was resolved, for future reuse. Over time most cases auto-resolve; the tool
|
|
121
|
-
asks only about genuine novelty. The accumulated ledger also **feeds Product's Field-ID /
|
|
122
|
-
template-entity-id** effort (we are the interim bridge that generates their data).
|
|
123
|
-
|
|
124
|
-
## 8. Diff MODALITIES — multiple diff forms for different processes (Oscar 2026-07-03)
|
|
125
|
-
|
|
126
|
-
There is **no single diff**. Different processes need different modes. Fields may **move between
|
|
127
|
-
sections**, or **must go to a specific section** — some processes care about section membership,
|
|
128
|
-
others only about the field's data pairing. The engine is a **family of strategies** over configurable
|
|
129
|
-
axes:
|
|
130
|
-
|
|
131
|
-
- **Pairing strategy:** by-id (self-version) · genome · type+label · assisted/ledger (cross-object).
|
|
132
|
-
- **Comparison scope:** structural (stages/sections/fields) · config-only (field configuration,
|
|
133
|
-
options, forces) · data-migration (field→field data pairing, structure-agnostic).
|
|
134
|
-
- **Move sensitivity:** section-move-aware vs section-agnostic; ordering-sensitive vs -insensitive.
|
|
135
|
-
- **Direction/intent:** changelog (what changed, for a ticket) · deployment delta (UAT→PROD replay) ·
|
|
136
|
-
sync-readiness (can this register/subset be synced to the active template?).
|
|
137
|
-
|
|
138
|
-
`Diff::VersionDiff` implements the **self-version, id-paired, structural, section-move-aware** mode.
|
|
139
|
-
The others compose the same `Change` output with a different pairing front-end and comparison scope.
|
|
140
|
-
|
|
141
|
-
## 9. Layering — where each capability lives (CONFIRMED)
|
|
142
|
-
|
|
143
|
-
| Layer | Owns | Consumers |
|
|
144
|
-
|---|---|---|
|
|
145
|
-
| **ecoportal-api-graphql** (gem) | *mechanics*: read model, WorkflowCommand vocab, build (emitter) + **diff (VersionDiff)** + apply; `genomeSignature` fragment (to add) | everyone |
|
|
146
|
-
| **eco-helpers** | *orchestration*: pairing engine (human-in-loop), learning ledger, samples, session flows, `TypedFieldsPairing` | tools, scripts |
|
|
147
|
-
| **ecoportal-qa** | QA-facing surface (checks/reporters/Jira/CLI); **should use the gem's model, not re-implement it** | QA team |
|
|
148
|
-
| admin / troubleshooting / integrations | consume gem + eco-helpers directly | — |
|
|
149
|
-
|
|
150
|
-
## 10. The pipeline (how the pieces compose)
|
|
151
|
-
|
|
152
|
-
```
|
|
153
|
-
pair (id | genome | type+label | assisted+ledger)
|
|
154
|
-
└─► diff on paired model (mode-specific)
|
|
155
|
-
└─► delta as WorkflowCommands (the emitter)
|
|
156
|
-
└─► apply to target ─► verify (ecoportal-qa) ─► monitor (register sync-ready tickboxes)
|
|
157
|
-
```
|
|
158
|
-
The **self-version changelog** is a portable "commit": a `Change` set that, once id-translated through
|
|
159
|
-
a pairing map, **replays onto PROD**.
|
|
160
|
-
|
|
161
|
-
## 11. Product context
|
|
162
|
-
|
|
163
|
-
Register-template-sync is **not yet scoped** by Product (Field-ID takes precedence). Product is working
|
|
164
|
-
out a **template-entity-id** to differentiate template versions within a register (to pair pages made
|
|
165
|
-
from a previous template version with the current one) + **customer filters by template**. Our tools
|
|
166
|
-
are the interim bridge and **generate the pairing data** Product needs.
|
|
167
|
-
|
|
168
|
-
## 12. Status & next steps
|
|
169
|
-
|
|
170
|
-
- ✅ **Done:** `Diff::VersionDiff` (self-version, exact, id-paired) — gem, 8 specs.
|
|
171
|
-
- **Next:** (1) add `genomeSignature` to the data-field fragment + `Base::Page::DataField`; (2) synthesise
|
|
172
|
-
WorkflowCommands from a `Change` set (delta → commands); (3) the **pairing engine** (equivalence,
|
|
173
|
-
multi-signal, human-assisted, ledger) in eco-helpers; (4) **diff modalities** as strategies;
|
|
174
|
-
(5) cross-template deploy (UAT→PROD replay); (6) monitoring / sync-readiness; (7) tighten `ecoportal-qa`
|
|
175
|
-
to use the gem's page-model instead of its own `TemplateModel`.
|