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,55 +0,0 @@
|
|
|
1
|
-
# CoWork Native Capabilities
|
|
2
|
-
|
|
3
|
-
Last verified: 2026-06-04
|
|
4
|
-
Environment: Claude desktop app — CoWork mode
|
|
5
|
-
|
|
6
|
-
## Can do natively
|
|
7
|
-
|
|
8
|
-
- Read, write, edit files in connected folders (including all of `.ai-assistance/`)
|
|
9
|
-
- Web search and page fetch
|
|
10
|
-
- Bash sandbox (Ubuntu 22, Python/Node preinstalled, allowlisted network)
|
|
11
|
-
- Create documents: .docx, .pptx, .xlsx, .pdf, .md, .html
|
|
12
|
-
- Render live HTML/React artifacts (persist across sessions)
|
|
13
|
-
- Scheduled tasks (while desktop app is open)
|
|
14
|
-
- Skills: docx, pptx, xlsx, pdf, and all installed plugin skills
|
|
15
|
-
|
|
16
|
-
## Cannot do
|
|
17
|
-
|
|
18
|
-
- Write or edit files under `.ai-assistance/` (application-layer guard on that path)
|
|
19
|
-
- Direct git operations (clone, push, pull, branch, commit)
|
|
20
|
-
- Install software on host machine
|
|
21
|
-
- Run commands outside the bash sandbox
|
|
22
|
-
- Access Code sessions or terminal history
|
|
23
|
-
- Use MCP servers defined in `claude_desktop_config.json` — those do not surface as
|
|
24
|
-
CoWork connectors. CoWork connectors are installed via Settings → Plugins only.
|
|
25
|
-
Verified 2026-06-04: GitLab and GitKraken written to Desktop config, neither
|
|
26
|
-
appeared as available connectors in CoWork.
|
|
27
|
-
|
|
28
|
-
## Connectors available in CoWork
|
|
29
|
-
|
|
30
|
-
See `connectors.md` for the full registry. Install via Settings → Plugins.
|
|
31
|
-
|
|
32
|
-
Confirmed available (2026-06-04):
|
|
33
|
-
- Google Workspace (Drive, Gmail, Calendar) — if authenticated
|
|
34
|
-
- Slack — if authenticated
|
|
35
|
-
- Notion — if authenticated
|
|
36
|
-
- HubSpot, Intercom, Asana, Linear, etc. — if plugin installed + authenticated
|
|
37
|
-
|
|
38
|
-
## When to use the bridge
|
|
39
|
-
|
|
40
|
-
The bridge is a **connector delegation service** — use it only when you need to call
|
|
41
|
-
a service that CoWork cannot reach. Do not bridge for working tree edits, documentation,
|
|
42
|
-
or anything in the "Can do natively" list above.
|
|
43
|
-
|
|
44
|
-
Bridge to Code when you need:
|
|
45
|
-
|
|
46
|
-
| Connector / service | Why Code has it |
|
|
47
|
-
|---------------------|-----------------|
|
|
48
|
-
| Gemini | Gemini MCP configured in Code |
|
|
49
|
-
| GitLab (MRs, pipelines, issues) | GitLab MCP configured in Code |
|
|
50
|
-
| GitKraken (git history, branches) | GitKraken MCP configured in Code |
|
|
51
|
-
| Unrestricted shell (host-level) | Code runs outside the sandbox |
|
|
52
|
-
|
|
53
|
-
Before writing a bridge task, check `connectors.md` to confirm the connector is
|
|
54
|
-
available and authenticated in Code. If status is `unknown` or `needs-setup`, note
|
|
55
|
-
that in the bridge task so Code can surface the issue.
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
# Code Spec: ecoportal-api-graphql — Gem Overview
|
|
2
|
-
|
|
3
|
-
**Scope:** High-level structure, entry points, key patterns, and namespace conventions for the whole gem. Does NOT cover per-area implementation detail — see area-specific docs in `.ai-assistance/code/` for those.
|
|
4
|
-
**Last updated:** 2026-06-02
|
|
5
|
-
**Key files:**
|
|
6
|
-
- `lib/ecoportal/api-graphql.rb` — gem entry point (requires upstream, boots namespace)
|
|
7
|
-
- `lib/ecoportal/api/graphql.rb` — main `Ecoportal::API::GraphQL` class
|
|
8
|
-
- `lib/ecoportal/api/common/graphql/client.rb` — GraphQL HTTP client (wraps graphlient)
|
|
9
|
-
- `ecoportal-api-graphql.gemspec` — gem spec and dependencies
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Overview
|
|
14
|
-
|
|
15
|
-
`ecoportal-api-graphql` provides a Ruby client for EcoPortal's GraphQL API. It wraps `graphlient` (which wraps `graphql-client`) and builds a structured layer of models, queries, mutations, fragments, inputs, payloads, and builders on top of it.
|
|
16
|
-
|
|
17
|
-
The gem is used primarily by `eco-helpers` (downstream). Backwards compatibility with `eco-helpers` must be preserved unless explicitly broken.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Dependency Chain
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
graphql-ruby (rmosolgo) — schema definition side (not directly used as a dep)
|
|
25
|
-
graphql-client — low-level HTTP+parsing
|
|
26
|
-
graphlient — friendlier wrapper around graphql-client (~> 0.8)
|
|
27
|
-
ecoportal-api (~> 0.10) — REST API base (auth, org context)
|
|
28
|
-
ecoportal-api-v2 (~> 3.3) — REST API v2 (required by entry point)
|
|
29
|
-
↓
|
|
30
|
-
ecoportal-api-graphql ← THIS GEM
|
|
31
|
-
↓
|
|
32
|
-
eco-helpers — downstream consumer
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Entry Point
|
|
38
|
-
|
|
39
|
-
`require 'ecoportal/api-graphql'` loads:
|
|
40
|
-
1. `ecoportal-api-v2` (and transitively `ecoportal-api`)
|
|
41
|
-
2. `ecoportal/api/graphql_version`
|
|
42
|
-
3. `ecoportal/api/common.graphql` — shared common GraphQL utilities
|
|
43
|
-
4. `ecoportal/api/graphql` — the main class + all sub-requires
|
|
44
|
-
|
|
45
|
-
Load order within `graphql.rb`:
|
|
46
|
-
`helpers` → `concerns` → `logic/base_model` → `error` → `interface` → `base` → `model` → `logic` → `connection` → `payload` → `input` → `fragment` → `query` → `mutation` → `builder`
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## Main Class: `Ecoportal::API::GraphQL`
|
|
51
|
-
|
|
52
|
-
The public entry point. Instantiated with credentials:
|
|
53
|
-
|
|
54
|
-
```ruby
|
|
55
|
-
api = Ecoportal::API::GraphQL.new(email: "...", pass: "...", org_id: "...", host: "live.ecoportal.com")
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Key public methods:
|
|
59
|
-
- `#currentOrganization` / `#currentOrganizationClass` — returns `Model::Organization` with client set
|
|
60
|
-
- `#contractorEntity` → `Builder::ContractorEntity`
|
|
61
|
-
- `#locationStructure` → `Builder::LocationStructure`
|
|
62
|
-
- `#action` → `Builder::Action`
|
|
63
|
-
- `#createContractorEntity(input:)` — convenience shortcut (delegates to mutation)
|
|
64
|
-
|
|
65
|
-
Includes `Common::GraphQL::ClassHelpers` for `class_resolver` — allows subclasses to override `client_class`.
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## Namespace Convention
|
|
70
|
-
|
|
71
|
-
**IMPORTANT:** The module is `Ecoportal::API::GraphQL` (capital Q, capital L) but Ruby casing — NOT `Ecoportal::API::GraphQl`. File paths use lowercase: `graphql/`.
|
|
72
|
-
|
|
73
|
-
Class nesting mirrors folder structure exactly:
|
|
74
|
-
|
|
75
|
-
| Folder | Module/Class |
|
|
76
|
-
|--------|-------------|
|
|
77
|
-
| `graphql/model/` | `GraphQL::Model::*` |
|
|
78
|
-
| `graphql/input/` | `GraphQL::Input::*` |
|
|
79
|
-
| `graphql/mutation/` | `GraphQL::Mutation::*` |
|
|
80
|
-
| `graphql/query/` | `GraphQL::Query::*` |
|
|
81
|
-
| `graphql/builder/` | `GraphQL::Builder::*` |
|
|
82
|
-
| `graphql/fragment/` | `GraphQL::Fragment::*` |
|
|
83
|
-
| `graphql/payload/` | `GraphQL::Payload::*` |
|
|
84
|
-
| `graphql/connection/` | `GraphQL::Connection::*` |
|
|
85
|
-
| `graphql/logic/` | `GraphQL::Logic::*` |
|
|
86
|
-
| `graphql/base/` | `GraphQL::Base::*` |
|
|
87
|
-
| `graphql/interface/` | `GraphQL::Interface::*` |
|
|
88
|
-
| `graphql/error/` | `GraphQL::Error::*` |
|
|
89
|
-
|
|
90
|
-
---
|
|
91
|
-
|
|
92
|
-
## Architectural Layers
|
|
93
|
-
|
|
94
|
-
```
|
|
95
|
-
Builder High-level façade — developer-facing API per domain
|
|
96
|
-
↓
|
|
97
|
-
Query / Mutation GraphQL operation definitions
|
|
98
|
-
↓
|
|
99
|
-
Logic Execution layer (base_query, base_model, query, mutation, payload, input, connection)
|
|
100
|
-
↓
|
|
101
|
-
Fragment GraphQL fragment strings
|
|
102
|
-
↓
|
|
103
|
-
Model Response data models (read side)
|
|
104
|
-
Input / Payload Mutation arguments (write side) and mutation responses
|
|
105
|
-
↓
|
|
106
|
-
Base Shared base classes for models
|
|
107
|
-
Interface GraphQL interface type definitions
|
|
108
|
-
↓
|
|
109
|
-
Common::GraphQL::Client HTTP layer (graphlient wrapper with auth)
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Common::GraphQL Layer
|
|
115
|
-
|
|
116
|
-
Lives in `lib/ecoportal/api/common/graphql/`. Key classes:
|
|
117
|
-
|
|
118
|
-
- `Client` — extends `Graphlient::Client`. Handles auth (`AuthService`), org_id, timeouts (90s read/write). `no_schema: true` skips schema introspection.
|
|
119
|
-
- `Model` — base model class for response parsing.
|
|
120
|
-
- `ClassHelpers` — `class_resolver` macro for dependency injection of class references.
|
|
121
|
-
- `HashHelpers` — hash utility methods.
|
|
122
|
-
- `QueryIntegration` — mixin for query execution.
|
|
123
|
-
- `Patches` — monkey-patches to upstream libs (review carefully before changing).
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
## Domain Objects
|
|
128
|
-
|
|
129
|
-
The gem covers these EcoPortal GraphQL domains:
|
|
130
|
-
|
|
131
|
-
| Domain | Builder | Key Model | Key Mutations |
|
|
132
|
-
|--------|---------|-----------|--------------|
|
|
133
|
-
| Location Structure | `Builder::LocationStructure` | `Model::LocationStructure` | draft create/delete/publish, apply_commands |
|
|
134
|
-
| Contractor Entity | `Builder::ContractorEntity` | `Model::ContractorEntity` | create, update, destroy |
|
|
135
|
-
| Action | `Builder::Action` | `Model::Action` | create, update, archive |
|
|
136
|
-
| Organization | — (direct on GraphQL class) | `Model::Organization` | — |
|
|
137
|
-
| Page | — | `Model::Page` | — |
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
## Gotchas / Non-Obvious Behaviours
|
|
142
|
-
|
|
143
|
-
- `no_schema: true` is always passed — schema introspection is disabled. Queries are not validated against a schema at build time.
|
|
144
|
-
- `GraphQL::Fragment` is instantiated at GraphQL init and passed around — it's a container for fragment string definitions.
|
|
145
|
-
- `Builder` classes take a `client` directly, not a `GraphQL` instance.
|
|
146
|
-
- `Logic::BaseModel` inherits from `Common::GraphQL::Model` and adds a class-level `client` accessor. Most model/query classes inherit from this.
|
|
147
|
-
- `class_resolver` (from `ClassHelpers`) allows subclasses to override which concrete class is used — important for testing and extension.
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## TODOs / Open Questions
|
|
152
|
-
|
|
153
|
-
- [ ] Per-area code spec docs need to be created as analysis progresses.
|
|
154
|
-
- [ ] `Common::GraphQL::Patches` contents not yet reviewed — may contain important behavioural notes.
|
|
155
|
-
- [ ] Spec coverage is minimal — `spec/ecoportal/api_spec.rb` exists but subdirectory coverage is sparse.
|
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
# Data Fields — Code Spec
|
|
2
|
-
|
|
3
|
-
*All 20 DataField types, access patterns, mutation input serialisation, and Collection API.*
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Overview
|
|
8
|
-
|
|
9
|
-
Data fields are the form inputs within a page (rich content — not structural metadata).
|
|
10
|
-
Each field is a live instance with a MongoDB ObjectId (`id`) assigned on page creation.
|
|
11
|
-
|
|
12
|
-
All field types inherit from `Base::Page::DataField < Logic::BaseModel` and live in
|
|
13
|
-
`lib/ecoportal/api/graphql/base/page/data_field/`.
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## All 20 Field Types
|
|
18
|
-
|
|
19
|
-
| GraphQL `__typename` | Ruby class | Writable | Input key |
|
|
20
|
-
|---|---|---|---|
|
|
21
|
-
| `PlainText` | `DataField::PlainText` | ✓ | `plainText` |
|
|
22
|
-
| `RichText` | `DataField::RichText` | ✓ | `richText` |
|
|
23
|
-
| `Date` | `DataField::DateField` | ✓ | `date` |
|
|
24
|
-
| `Number` | `DataField::Number` | ✓ | `number` |
|
|
25
|
-
| `Gauge` | `DataField::Gauge` | ✓ | `gauge` |
|
|
26
|
-
| `Select` | `DataField::Select` | ✓ | `select` |
|
|
27
|
-
| `Checklist` | `DataField::Checklist` | ✓ | `checklist` |
|
|
28
|
-
| `TagField` | `DataField::TagField` | ✓ | `locationField` |
|
|
29
|
-
| `People` | `DataField::People` | ✓ | `people` |
|
|
30
|
-
| `Geo` | `DataField::Geo` | ✓ | `geo` |
|
|
31
|
-
| `ContractorEntities` | `DataField::ContractorEntities` | ✓ | `contractorEntities` |
|
|
32
|
-
| `CrossReference` | `DataField::CrossReference` | ✓ | `crossReference` |
|
|
33
|
-
| `File` | `DataField::FileField` | ✓* | `file` |
|
|
34
|
-
| `ImageGallery` | `DataField::ImageGallery` | ✓* | `imageGallery` |
|
|
35
|
-
| `Signature` | `DataField::Signature` | — | — |
|
|
36
|
-
| `Mailbox` | `DataField::Mailbox` | — | — |
|
|
37
|
-
| `ActionsList` | `DataField::ActionsList` | — | — |
|
|
38
|
-
| `Law` | `DataField::Law` | — | — |
|
|
39
|
-
| `AiSummary` | `DataField::AiSummary` | — | — |
|
|
40
|
-
| `Table` | `DataField::Table` | — | — |
|
|
41
|
-
|
|
42
|
-
\* File and ImageGallery require a prior file upload to the REST upload endpoint to obtain
|
|
43
|
-
`fileContainerIds`. See `projects/TODO.md` — "File upload" item.
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Dispatch
|
|
48
|
-
|
|
49
|
-
`DataField.from_doc(raw_hash)` reads `__typename` (or `type` if already normalised) and
|
|
50
|
-
returns the right subclass instance. Falls back to base `DataField` for unknown types.
|
|
51
|
-
|
|
52
|
-
```ruby
|
|
53
|
-
field = Base::Page::DataField.from_doc({ '__typename' => 'PlainText', 'id' => 'f1', 'value' => 'X' })
|
|
54
|
-
# => #<DataField::PlainText ...>
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## Field Access on Page Models
|
|
60
|
-
|
|
61
|
-
`Interface::BasePage` includes `Concerns::DataFieldAccess`, so all concrete page models have:
|
|
62
|
-
|
|
63
|
-
```ruby
|
|
64
|
-
page.field_collection # → DataField::Collection (memoized)
|
|
65
|
-
page.components # → same (v2 compat alias)
|
|
66
|
-
page.data_fields_updates # → [DataFieldInput, ...] for dirty fields
|
|
67
|
-
page.data_fields_additions # → [DataFieldInput, ...] for added fields
|
|
68
|
-
page.data_fields_deletions # → [field_id, ...] queued for deletion
|
|
69
|
-
page.data_fields_dirty? # → Boolean
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
`Base::Page::Phased::Stage` also exposes `components` (via `sections.components`) for
|
|
73
|
-
stage-level field access.
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## DataField::Collection API
|
|
78
|
-
|
|
79
|
-
```ruby
|
|
80
|
-
coll = page.components
|
|
81
|
-
|
|
82
|
-
# Read
|
|
83
|
-
coll.get_by_type(:plain_text) # → [DataField::PlainText, ...]
|
|
84
|
-
coll.get_by_type('PlainText') # → same (string also works)
|
|
85
|
-
coll.get_by_name('Summary') # → DataField::PlainText (case-insensitive)
|
|
86
|
-
|
|
87
|
-
# Iterate
|
|
88
|
-
coll.each { |f| puts f.label }
|
|
89
|
-
coll.map(&:label)
|
|
90
|
-
|
|
91
|
-
coll.doc # → [raw_hash, ...] (v2 compat)
|
|
92
|
-
coll.empty? # → Boolean
|
|
93
|
-
coll.length # → Integer
|
|
94
|
-
|
|
95
|
-
# Mutations — updates (existing fields)
|
|
96
|
-
field = coll.get_by_name('Summary')
|
|
97
|
-
field.value = 'New text'
|
|
98
|
-
coll.dirty_inputs # → [{ plainText: { id: 'f1', value: 'New text' } }]
|
|
99
|
-
|
|
100
|
-
# Mutations — additions (new field instances from buildFromTemplate)
|
|
101
|
-
coll.add(id: 'server_id', label: 'New Field', type: 'PlainText') { |f| f.value = 'X' }
|
|
102
|
-
coll.dirty_additions # → [{ plainText: { id: 'server_id', value: 'X' } }]
|
|
103
|
-
|
|
104
|
-
# Mutations — deletions (remove field instances)
|
|
105
|
-
coll.mark_for_deletion('f1') # by ID string
|
|
106
|
-
coll.mark_for_deletion(field_object) # by field object (uses field.id)
|
|
107
|
-
coll.dirty_deletions # → ['f1']
|
|
108
|
-
|
|
109
|
-
coll.dirty? # → true if any of the above have changes
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Setter API per Type
|
|
115
|
-
|
|
116
|
-
### PlainText
|
|
117
|
-
```ruby
|
|
118
|
-
field.value = 'text string'
|
|
119
|
-
field.as_input # → { plainText: { id:, value: } }
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### RichText
|
|
123
|
-
```ruby
|
|
124
|
-
field.content = '<p>HTML</p>'
|
|
125
|
-
field.value = '<p>HTML</p>' # alias
|
|
126
|
-
field.as_input # → { richText: { id:, content: } }
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
### Date
|
|
130
|
-
```ruby
|
|
131
|
-
field.value = '2025-06-30T09:00:00+12:00' # ISO8601
|
|
132
|
-
field.as_input # → { date: { id:, value: } }
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Number / Gauge
|
|
136
|
-
```ruby
|
|
137
|
-
field.value = 42.5
|
|
138
|
-
field.as_input # → { number: { id:, value: } } or { gauge: { id:, value: } }
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Select
|
|
142
|
-
```ruby
|
|
143
|
-
field.select_option('Active') # select by name (deselects all others)
|
|
144
|
-
field.select_option('o1') # select by option id
|
|
145
|
-
field.select_option('opt1', 'opt2') # multi-select by id
|
|
146
|
-
field.clear_selection
|
|
147
|
-
field.selected_options # → [{ 'id' =>..., 'name' =>..., 'selected' => true }]
|
|
148
|
-
field.as_input # → { select: { id:, options: [{ id:, selected: }] } }
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### Checklist
|
|
152
|
-
```ruby
|
|
153
|
-
field.check('Step A') # check by label
|
|
154
|
-
field.check('i1', checked: false) # uncheck by id
|
|
155
|
-
field.as_input # → { checklist: { id:, items: [{ id:, checked: }] } }
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### TagField (LocationField)
|
|
159
|
-
```ruby
|
|
160
|
-
field.location_ids = ['loc1', 'loc2']
|
|
161
|
-
field.as_input # → { locationField: { id:, locationIds: [...] } }
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### People
|
|
165
|
-
```ruby
|
|
166
|
-
field.people_ids = ['person1', 'person2']
|
|
167
|
-
field.value = ['person1'] # alias
|
|
168
|
-
field.as_input # → { people: { id:, peopleIds: [...] } }
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### Geo
|
|
172
|
-
```ruby
|
|
173
|
-
field.address = '123 Main St, Auckland'
|
|
174
|
-
field.coordinates = { 'lat' => -36.86, 'lon' => 174.76 }
|
|
175
|
-
field.as_input # → { geo: { id:, address:, coordinates: } }
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### ContractorEntities
|
|
179
|
-
```ruby
|
|
180
|
-
field.contractor_entity_ids = ['ce1', 'ce2']
|
|
181
|
-
field.value = ['ce1'] # alias
|
|
182
|
-
field.as_input # → { contractorEntities: { id:, contractorEntityIds: [...] } }
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### CrossReference
|
|
186
|
-
```ruby
|
|
187
|
-
field.page_ids = ['page1', 'page2']
|
|
188
|
-
field.as_input # → { crossReference: { id:, referenceIds: [...] } }
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### File / ImageGallery
|
|
192
|
-
```ruby
|
|
193
|
-
# Requires prior file upload — see TODO "File upload"
|
|
194
|
-
field.file_container_ids = ['fc1', 'fc2']
|
|
195
|
-
field.as_input # → { file: { id:, fileContainerIds: [...] } }
|
|
196
|
-
# or { imageGallery: { id:, fileContainerIds: [...] } }
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
## DataFieldOneToManyInput — Wiring to Mutations
|
|
202
|
-
|
|
203
|
-
`Input::Page::Update.from_model(page)` automatically collects field changes:
|
|
204
|
-
|
|
205
|
-
```ruby
|
|
206
|
-
input = Input::Page::Update.from_model(page)
|
|
207
|
-
# input[:dataFields] may contain:
|
|
208
|
-
# {
|
|
209
|
-
# updates: [{ plainText: { id:, value: } }, ...], # dirty existing fields
|
|
210
|
-
# additions: [{ plainText: { id:, value: } }, ...], # newly added fields
|
|
211
|
-
# deletions: ['field_id_1', 'field_id_2'] # fields queued for deletion
|
|
212
|
-
# }
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
`build_data_fields` only includes non-empty keys — if only `updates` exist, only
|
|
216
|
-
`updates` is present in the hash.
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
## Stage-Level Field Access
|
|
221
|
-
|
|
222
|
-
```ruby
|
|
223
|
-
page = graphql.pages.get(page_id)
|
|
224
|
-
stage = page.stages['Risk Assessment']
|
|
225
|
-
|
|
226
|
-
# All fields in the stage (flat, across sections)
|
|
227
|
-
stage.components.get_by_name('Hazard Description').value = 'Exposure to...'
|
|
228
|
-
|
|
229
|
-
# Section-by-section
|
|
230
|
-
stage.sections.each do |section|
|
|
231
|
-
section.components.each { |f| puts "#{f.label}: #{f.value}" }
|
|
232
|
-
end
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
---
|
|
236
|
-
|
|
237
|
-
## Spec Coverage
|
|
238
|
-
|
|
239
|
-
| File | Coverage |
|
|
240
|
-
|---|---|
|
|
241
|
-
| `spec/ecoportal/api/graphql/base/page/data_field_spec.rb` | All 20 type dispatch, dirty tracking, PlainText, RichText, Select, People, Checklist, Collection (get_by_type/name, dirty_inputs, add/additions, deletions) |
|
|
242
|
-
| `spec/ecoportal/api/graphql/input/page/update_spec.rb` | from_model with dataFields.updates, additions, deletions |
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
# Code Spec: Dependency Map
|
|
2
|
-
|
|
3
|
-
**Scope:** All upstream and downstream gem dependencies for `ecoportal-api-graphql` — remote URLs, fork relationships, collaboration status, and access notes. Local paths are developer-specific; see the section below on local setup.
|
|
4
|
-
**Last updated:** 2026-06-02
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## This Repo
|
|
9
|
-
|
|
10
|
-
| Property | Value |
|
|
11
|
-
|----------|-------|
|
|
12
|
-
| Gem name | `ecoportal-api-graphql` |
|
|
13
|
-
| Remote (origin) | https://gitlab.ecoportal.co.nz/oscar/ecoportal-api-graphql.git |
|
|
14
|
-
| Relationship | Target repo — all work happens here |
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## Upstream Dependencies
|
|
19
|
-
|
|
20
|
-
### ecoportal-api
|
|
21
|
-
|
|
22
|
-
| Property | Value |
|
|
23
|
-
|----------|-------|
|
|
24
|
-
| Gem name | `ecoportal-api` |
|
|
25
|
-
| Version constraint | `~> 0.10, >= 0.10.15` |
|
|
26
|
-
| Remote | https://gitlab.ecoportal.co.nz/ecoportal/ecoportal-api.git |
|
|
27
|
-
| Collaboration | **Team-managed** — we own this gem |
|
|
28
|
-
| Key deps | `dotenv`, `elastic-apm`, `http`, `rate_throttle_client` |
|
|
29
|
-
| Notes | Provides REST API base, authentication, org context, and the `Ecoportal::API::Common` namespace that this gem extends. |
|
|
30
|
-
|
|
31
|
-
### ecoportal-api-v2
|
|
32
|
-
|
|
33
|
-
| Property | Value |
|
|
34
|
-
|----------|-------|
|
|
35
|
-
| Gem name | `ecoportal-api-v2` |
|
|
36
|
-
| Version constraint | `~> 3.3, >= 3.3.1` |
|
|
37
|
-
| Remote | https://gitlab.ecoportal.co.nz/oscar/ecoportal-api-v2.git |
|
|
38
|
-
| Collaboration | **Team-managed** — we own this gem |
|
|
39
|
-
| Key deps | `ecoportal-api`, `mime-types` |
|
|
40
|
-
| Notes | REST API v2 layer. Required by the entry point (`api-graphql.rb`). Depends on `ecoportal-api` itself. |
|
|
41
|
-
|
|
42
|
-
### graphlient
|
|
43
|
-
|
|
44
|
-
| Property | Value |
|
|
45
|
-
|----------|-------|
|
|
46
|
-
| Gem name | `graphlient` |
|
|
47
|
-
| Version constraint | `>= 0.8.0, < 0.9` |
|
|
48
|
-
| Remote (our fork) | https://github.com/rellampec/graphlient.git |
|
|
49
|
-
| Remote (upstream) | https://github.com/ashkan18/graphlient.git |
|
|
50
|
-
| Collaboration | **Fork (active)** — we drive new features; upstream is `ashkan18/graphlient` |
|
|
51
|
-
| Git workflow | **Feature branches off our fork's working branch** (`feature/directives-dsl-support`). We open PRs upstream when appropriate but are not required to. Do NOT commit directly to `master`. |
|
|
52
|
-
| Key deps | `faraday ~> 2.0`, `graphql-client` |
|
|
53
|
-
| Notes | Friendly wrapper around `graphql-client`. `Common::GraphQL::Client` inherits from `Graphlient::Client`. |
|
|
54
|
-
|
|
55
|
-
### graphql-client
|
|
56
|
-
|
|
57
|
-
| Property | Value |
|
|
58
|
-
|----------|-------|
|
|
59
|
-
| Gem name | `graphql-client` |
|
|
60
|
-
| Version constraint | (via graphlient) |
|
|
61
|
-
| Remote (our fork) | https://github.com/rellampec/graphql-client.git |
|
|
62
|
-
| Remote (upstream) | https://github.com/github-community-projects/graphql-client.git |
|
|
63
|
-
| Collaboration | **Fork (upstream-contribution only)** — we do NOT maintain this gem; upstream is `github-community-projects/graphql-client` |
|
|
64
|
-
| Git workflow | **ALWAYS use a feature branch** (e.g. `feature/allow-named-fragment-access`). Changes are intended as upstream PRs to `github-community-projects/graphql-client`. NEVER commit to `master`. If unsure about the branch name or PR strategy, ask the developer before committing. |
|
|
65
|
-
| Key deps | `activesupport >= 3.0`, `graphql >= 1.13.0` |
|
|
66
|
-
| Notes | Low-level GraphQL HTTP + parsing library. Pulled in transitively via `graphlient` — not a direct dependency. Check `Common::GraphQL::Patches` for any monkey-patches applied on top. |
|
|
67
|
-
|
|
68
|
-
### graphql-ruby
|
|
69
|
-
|
|
70
|
-
| Property | Value |
|
|
71
|
-
|----------|-------|
|
|
72
|
-
| Gem name | `graphql` |
|
|
73
|
-
| Version constraint | `>= 1.13.0` (transitive, via graphql-client) |
|
|
74
|
-
| Remote | https://github.com/rmosolgo/graphql-ruby |
|
|
75
|
-
| Collaboration | **No collaboration** — external, read-only reference |
|
|
76
|
-
| Notes | Schema definition and execution engine. Used server-side by EcoPortal; client-side usage here is indirect. API reference: https://graphql-ruby.org |
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## Downstream Dependencies
|
|
81
|
-
|
|
82
|
-
### eco-helpers
|
|
83
|
-
|
|
84
|
-
| Property | Value |
|
|
85
|
-
|----------|-------|
|
|
86
|
-
| Gem name | `eco-helpers` |
|
|
87
|
-
| Requires this gem as | `ecoportal-api-graphql ~> 1.3, >= 1.3.4` |
|
|
88
|
-
| Remote | https://gitlab.ecoportal.co.nz/oscar/script_api_helpers.git |
|
|
89
|
-
| Collaboration | **Team-managed** — we own this gem |
|
|
90
|
-
| Notes | Primary consumer of this gem. **Backwards compatibility with `eco-helpers` must be preserved.** When a change could break it, cross-reference its usage before committing. |
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## Dependency Chain Summary
|
|
95
|
-
|
|
96
|
-
```
|
|
97
|
-
graphql-ruby (rmosolgo — external, read-only)
|
|
98
|
-
↓
|
|
99
|
-
graphql-client (our fork ← github-community-projects/graphql-client)
|
|
100
|
-
↓
|
|
101
|
-
graphlient (our fork ← ashkan18/graphlient)
|
|
102
|
-
↓
|
|
103
|
-
ecoportal-api (team-managed — gitlab.ecoportal.co.nz)
|
|
104
|
-
ecoportal-api-v2 (team-managed — gitlab.ecoportal.co.nz)
|
|
105
|
-
↓
|
|
106
|
-
ecoportal-api-graphql ← THIS REPO
|
|
107
|
-
↓
|
|
108
|
-
eco-helpers (team-managed — gitlab.ecoportal.co.nz)
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
## Local Development Setup
|
|
114
|
-
|
|
115
|
-
Local paths are **developer-specific** — do not hardcode them in shared docs.
|
|
116
|
-
|
|
117
|
-
Each developer who works across multiple gems should clone the relevant repos and record their local paths in `.claude/local_paths.md` (git-ignored). See `.claude/local_paths.example.md` for the format.
|
|
118
|
-
|
|
119
|
-
### Using local gem overrides with Bundler
|
|
120
|
-
|
|
121
|
-
To point Bundler at a local clone instead of the published gem:
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
bundle config local.ecoportal-api /your/path/to/ecoportal-api
|
|
125
|
-
bundle config local.ecoportal-api-v2 /your/path/to/ecoportal-api-v2
|
|
126
|
-
bundle config local.graphlient /your/path/to/graphlient
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
Or add a `path:` entry in `Gemfile` during development (remove before committing):
|
|
130
|
-
|
|
131
|
-
```ruby
|
|
132
|
-
gem 'graphlient', path: '/your/path/to/graphlient'
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### For AI agents working with local clones
|
|
136
|
-
|
|
137
|
-
1. Check `.ai-assistance/local_paths.md` for this developer's local paths.
|
|
138
|
-
2. If the file doesn't exist, the repos are not locally available — use the remote URLs for reference only (read via web fetch or ask the developer to clone).
|
|
139
|
-
3. Never assume a specific local path exists — always check first.
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## Upstream Change Decision Guide
|
|
144
|
-
|
|
145
|
-
If a task requires changes in an upstream gem, the options are (confirm with developer before proceeding):
|
|
146
|
-
|
|
147
|
-
1. **Local monkey-patch** — apply the fix from within `ecoportal-api-graphql` (see `Common::GraphQL::Patches`). Fast, contained, but temporary debt.
|
|
148
|
-
2. **Fork change** — commit to our fork (for `graphlient` or `graphql-client`). Appropriate for lasting fixes we own.
|
|
149
|
-
3. **New version** — for `ecoportal-api` or `ecoportal-api-v2` (team-owned), cut a new version. For external forks, optionally contribute back upstream.
|
|
150
|
-
|
|
151
|
-
Document the decision in the active project's `DECISIONS.md`.
|