ecoportal-api-graphql 2.2.0 → 2.2.1
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 +52 -31
- data/lib/ecoportal/api/common/graphql/model/diffable/leaf_diff_service.rb +1 -1
- data/lib/ecoportal/api/graphql/base/page/data_field/collection.rb +1 -1
- data/lib/ecoportal/api/graphql/compat/filter_translator.rb +1 -1
- data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +2 -2
- data/lib/ecoportal/api/graphql/fragment/permissions.rb +0 -2
- data/lib/ecoportal/api/graphql/input/page/update.rb +2 -2
- data/lib/ecoportal/api/graphql/input/search_conf.rb +1 -1
- data/lib/ecoportal/api/graphql/input/workflow_command/edit_template_container_uid.rb +1 -1
- data/lib/ecoportal/api/graphql/input/workflow_command/manage_copy_page_configuration.rb +1 -1
- data/lib/ecoportal/api/graphql/input/workflow_command/move_section_to_stage.rb +33 -0
- data/lib/ecoportal/api/graphql/input/workflow_command.rb +2 -0
- data/lib/ecoportal/api/graphql/logic/base_query.rb +1 -1
- data/lib/ecoportal/api/graphql/model/permissions.rb +6 -0
- data/lib/ecoportal/api/graphql/query/pages.rb +1 -1
- data/lib/ecoportal/api/graphql/query/permissions.rb +1 -1
- data/lib/ecoportal/api/graphql_version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 128e83d1aa8d0fa5b9e4ce95f8bbd5f8bd4f219ea7d7a94dd18ec31225ac3ce9
|
|
4
|
+
data.tar.gz: 7d79138b320e6ba09221bd79a4c341ef9dc039f4ccf6923567f3f4b36f657c27
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 04cb9487e78e2f11b4c71572bc17915570a8638da67df94cfa27f0dfb3400d2c9f67bcaf25ac1b5bb61f86f1884f5af88b3adf961528ef8d3e5567607fcc1140
|
|
7
|
+
data.tar.gz: 3036e3e2295a5a2eb5876e66b145d09f3fd1a96fc174234f77621b0cd553ad2e501dc4d9c1baf74077990d9ed03c77e9bb8c8858cec97005e7dbefbeb05bda45
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.2.1] - 2026-09-30
|
|
6
|
+
|
|
7
|
+
### Security
|
|
8
|
+
|
|
9
|
+
- Security republish of `2.2.0` -- backwards-compatible: removes customer and internal identifiers
|
|
10
|
+
from shipped comments and this changelog. Packaging is unchanged: `2.2.0` already shipped only
|
|
11
|
+
allowlisted files (`lib/**/*.rb` plus the named root docs).
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **Fixed:** `api.permissions` (`Query::Permissions`) failed against live after the 2026-09-29
|
|
16
|
+
platform release, which removed `Permissions.pageSmartAssistantCanChat` and
|
|
17
|
+
`Permissions.registerAssistantCanChat` (smart-assistant consolidation). `Fragment::Permissions` no
|
|
18
|
+
longer selects them. The model accessors are kept, deprecated, and now always return `nil`, so
|
|
19
|
+
callers do not break. Affects every earlier version, including 2.2.0.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **Added:** `WorkflowCommand` builder for `moveSectionToStage` (new in the 2026-09-29 live schema):
|
|
24
|
+
`build(:moveSectionToStage, source_stage_id:, target_stage_id:, section_id:, anchorId:, anchorPosition:)`,
|
|
25
|
+
moving an existing section to another stage. `anchorPosition` is validated like the other anchor commands.
|
|
26
|
+
|
|
5
27
|
## [2.2.0] - 2026-09-02
|
|
6
28
|
|
|
7
29
|
★ **This release supersedes 2.1.0, which was version-bumped and changelogged on 2026-08-21 but never
|
|
@@ -51,7 +73,7 @@ caller adapting to this is changing working-looking code.
|
|
|
51
73
|
`ximport` tooltip guard: fields marked exclude-from-import are counted and protected, never
|
|
52
74
|
treated as overwritable. `Delta.call`'s `reviewer:` seam is now wired to `Review.method(:call)`,
|
|
53
75
|
so `review_findings` appears in the delta payload. Gated by `tools/template_yaml/compare_gate.rb`
|
|
54
|
-
against
|
|
76
|
+
against a customer's 18 templates -- refusal set matches the Python exactly.
|
|
55
77
|
|
|
56
78
|
- `tools/template_yaml/model.rb`: Ruby port of the template projector's `project(doc, source)`
|
|
57
79
|
(P3's IR assembly), composing field and force walks into a compact IR dict with key order
|
|
@@ -73,7 +95,7 @@ caller adapting to this is changing working-looking code.
|
|
|
73
95
|
-> `UpdateGate`) over the `*.json` corpus, Python via a single batched subprocess (direct
|
|
74
96
|
import of `ep_template_yaml.py`, not its CLI) over the `*.yaml` corpus -- and diffs the ENTIRE
|
|
75
97
|
IR: every template attribute, every field, every force (incl. bindings), every review finding,
|
|
76
|
-
and the `update_gate` refusal set. Live run over
|
|
98
|
+
and the `update_gate` refusal set. Live run over a customer's 18 templates: **`P8 GATE: PASS`**,
|
|
77
99
|
0 unexpected divergences, 12 expected (the six known-corrected ObjectIds, each seen twice --
|
|
78
100
|
once as a field id, once as a binding `reference_id`).
|
|
79
101
|
- `tools/template_yaml/known_divergences.rb`: the six-id whitelist and its `corrupted_id?` rule,
|
|
@@ -116,9 +138,9 @@ caller adapting to this is changing working-looking code.
|
|
|
116
138
|
- **Fixed** `Common::GraphQL::ResponseError` discarding `errors[].extensions`. It now carries the
|
|
117
139
|
raw error entries and exposes `#errors`, `#extensions`, `#codes`, `#details`, `#full_messages`
|
|
118
140
|
and `#unauthorized?`. This is what makes a permission problem distinguishable from a request
|
|
119
|
-
problem in Ruby — the diagnosis
|
|
141
|
+
problem in Ruby — the diagnosis a customer integration pack tells customers to perform, which until now no tool
|
|
120
142
|
built on this gem could actually follow. The message still LEADS with the joined server messages
|
|
121
|
-
(existing matchers keep working) and appends `code:` / `details:` after them. `tools
|
|
143
|
+
(existing matchers keep working) and appends `code:` / `details:` after them. `tools/<customer>/cli.rb`
|
|
122
144
|
now reports the server's own classification instead of sniffing the message for `/unauthoriz/i` —
|
|
123
145
|
a sniff that could not tell a policy refusal from a FIELD-level gate. Tracked as Q-27.
|
|
124
146
|
|
|
@@ -212,30 +234,30 @@ closes.
|
|
|
212
234
|
`include` / `enforce`) for copy-page behaviour. Closes the last gap in the command bus --
|
|
213
235
|
`validate-queries` now reports 106/106 commands wired.
|
|
214
236
|
|
|
215
|
-
- `tools
|
|
237
|
+
- `tools/<customer>/collection.rb` -- a pure-Ruby, stdlib-only read interface over a customer's Postman "ALL
|
|
216
238
|
CASES" master collection (the sibling `ep-api-collections` repo masters it; this gem never
|
|
217
239
|
hand-copies its knowledge). Walks the folder tree, exposes each GraphQL request's full path,
|
|
218
240
|
name, query, parsed variables, and `{{placeholder}}` inventory, with a name/path lookup that
|
|
219
241
|
tolerates a folder-path prefix and raises a named error listing near-matches when nothing
|
|
220
|
-
resolves. `spec/tools
|
|
242
|
+
resolves. `spec/tools/<customer>/collection_sync_spec.rb` pins the webhook-admin and build/update-page
|
|
221
243
|
request paths plus the placeholders the tooling depends on, and fails -- naming exactly what
|
|
222
244
|
disappeared -- if the collection renames or removes one of them; it skips cleanly (not fails)
|
|
223
|
-
when no sibling checkout is present. See `tools
|
|
245
|
+
when no sibling checkout is present. See `tools/<customer>/README.md`.
|
|
224
246
|
|
|
225
247
|
- `tools/template_yaml/mns_review.py` -- cross-template audit over a directory of IR projections:
|
|
226
248
|
identifier coverage, `templateContainerUid` uniqueness and name plausibility, findings by code,
|
|
227
249
|
authoring-maturity signal, and classification of orphaned force bindings into projector gaps
|
|
228
250
|
versus real defects (checked against the source dumps). First run recorded in
|
|
229
|
-
`tools/template_yaml/reviews/2026-08-09
|
|
251
|
+
`tools/template_yaml/reviews/2026-08-09-<customer>-18-templates.md`.
|
|
230
252
|
|
|
231
|
-
- **`tools
|
|
253
|
+
- **`tools/<customer>/cli.rb`** -- a Ruby CLI that creates/lists/destroys a customer's webhook
|
|
232
254
|
subscription and verifies the setup read-only, runnable from a support server with nothing
|
|
233
|
-
but `USER_EMAIL`/`USER_PASS` supplied (every other value defaults to
|
|
255
|
+
but `USER_EMAIL`/`USER_PASS` supplied (every other value defaults to a customer UAT org, EU
|
|
234
256
|
instance). `webhook create` is idempotent in practice: it lists first and reports the
|
|
235
257
|
existing subscription instead of creating a duplicate when one already matches the URL and
|
|
236
258
|
template(s). `--dry-run` prints the GraphQL document and variables with no network call.
|
|
237
|
-
Document builders live in `tools
|
|
238
|
-
functions, spec'd in `spec/tools
|
|
259
|
+
Document builders live in `tools/<customer>/webhooks.rb` (`<Customer>Webhooks::Documents`) as pure
|
|
260
|
+
functions, spec'd in `spec/tools/<customer>/webhooks_spec.rb` with no network involved.
|
|
239
261
|
|
|
240
262
|
- **`Query::PersonMembers`** — the GraphQL-native people-directory path over
|
|
241
263
|
`organization.personMembers`, filling the gap flagged in `model/organization.rb`. Salvaged
|
|
@@ -286,7 +308,7 @@ closes.
|
|
|
286
308
|
bumping **neither `patchVer` nor `updatedAt`** — any watermark-polling change tracker is blind to
|
|
287
309
|
force-driven change, whereas the command log is per-change. (Open: whether forces run against
|
|
288
310
|
templates specifically is not confirmed.)
|
|
289
|
-
Also documented in
|
|
311
|
+
Also documented in the repo's internal docs.
|
|
290
312
|
|
|
291
313
|
- **New tool `tools/template_yaml/delta.rb`** (P6 of the template-YAML-tooling Ruby port): the
|
|
292
314
|
deterministic before/after difference between two `project()` snapshots, shaped for the Rovo
|
|
@@ -318,9 +340,9 @@ closes.
|
|
|
318
340
|
LAYOUT order -- `flow_nodes` by `weight`, then `membrane_ids` / `left_membrane_ids` /
|
|
319
341
|
`right_membrane_ids`, then each id list in stored order -- porting the Python projector's
|
|
320
342
|
`walk_fields` against the contract frozen in `P1-CONTRACT.md`.
|
|
321
|
-
**Verified against the real 18-template
|
|
343
|
+
**Verified against the real 18-template customer dump set: 2,714 fields, ids and ordering match the
|
|
322
344
|
Python projector exactly, with 0 unexpected divergences.** The only 6 differences are the
|
|
323
|
-
`ActionsList` ids the Python's YAML path corrupts (`
|
|
345
|
+
`ActionsList` ids the Python's YAML path corrupts (a contiguous run of `ActionsList` ids), where
|
|
324
346
|
the Ruby is correct and the Python is not; `compare_fields.rb` whitelists those six BY VALUE,
|
|
325
347
|
so a seventh divergence -- or any ordering defect on that same template -- still fails.
|
|
326
348
|
- **`FieldWalker` distinguishes "no fields" from "could not see the fields"**, which the Python
|
|
@@ -341,11 +363,11 @@ closes.
|
|
|
341
363
|
Reading JSON instead of YAML is deliberate: the Python projector's YAML path decodes
|
|
342
364
|
`!ruby/object:BSON::ObjectId` via a step with a silent-failure mode (confirmed unchanged on
|
|
343
365
|
the canonical post-!86 surface in `P1-CONTRACT.md`) that corrupts 6 of 2,432 fields on one
|
|
344
|
-
|
|
366
|
+
customer template without affecting counts. The JSON export carries identical data with plain hex
|
|
345
367
|
ids already, so the whole decode-bug class is structurally impossible on this path rather
|
|
346
|
-
than reimplemented. Verified against the real 18-template
|
|
368
|
+
than reimplemented. Verified against the real 18-template customer JSON dump set, including the 6
|
|
347
369
|
previously-corrupted `ActionsList` ids on "Yard 5S Site Standard"
|
|
348
|
-
(`
|
|
370
|
+
(a contiguous run of `ActionsList` ids), which load and validate correctly.
|
|
349
371
|
|
|
350
372
|
### Changed
|
|
351
373
|
|
|
@@ -372,8 +394,7 @@ Major release: everything accumulated on `main` since `v1.3.14` — the 2026-07-
|
|
|
372
394
|
schema syncs, command-bus completion (105/105 commands), native file upload, and a long run of
|
|
373
395
|
correctness fixes. **Breaking, but narrowly:** every removed or reshaped surface either targeted
|
|
374
396
|
a mutation the live schema never had (so it could never have worked) or was a dead accessor with
|
|
375
|
-
no consumer — a 2026-07-30 sweep of `eco-helpers
|
|
376
|
-
`multi-org-idle` found no consumer of any breaking surface (re-confirmed 2026-08-12). The major
|
|
397
|
+
no consumer — a 2026-07-30 sweep of `eco-helpers` and three internal script repos found no consumer of any breaking surface (re-confirmed 2026-08-12). The major
|
|
377
398
|
bump is deliberate: consumer repos declare `~> 1.3` (which allows 1.4.x), so a minor would have
|
|
378
399
|
been adopted silently on the next `bundle update`; 2.0.0 makes adoption a per-repo decision.
|
|
379
400
|
|
|
@@ -387,7 +408,7 @@ Note: this release does not descend from `v1.3.15`, which shipped from the `rele
|
|
|
387
408
|
branch forked at 1.3.14 — do not expect a linear tag history.
|
|
388
409
|
|
|
389
410
|
★ **The published gem is now `lib/` only.** `spec.files` excluded just `test|spec|features`, so
|
|
390
|
-
every top-level directory added since shipped by default — 244 files of internal
|
|
411
|
+
every top-level directory added since shipped by default — 244 files of internal AI-tooling
|
|
391
412
|
notes, `docs/` (including the rolling worklog), and `.claude/`. `spec.files` is now an allowlist
|
|
392
413
|
(`lib/`, `exe/`, README, LICENSE, CHANGELOG), which also drops the package from 959 KB to 195 KB.
|
|
393
414
|
All 568 `lib/` files are unchanged; nothing outside `lib/` was ever loaded at runtime.
|
|
@@ -430,7 +451,7 @@ All 568 `lib/` files are unchanged; nothing outside `lib/` was ever loaded at ru
|
|
|
430
451
|
but only one may be published (`active: true`) per organization at a time — publishing another
|
|
431
452
|
with the same uid unpublishes the incumbent. Previously the value was fetchable from the API but
|
|
432
453
|
unreachable through the gem (the embed was commented out and no fragment selected it).
|
|
433
|
-
Semantics documented in
|
|
454
|
+
Semantics documented in the repo's internal docs.
|
|
434
455
|
- **`editTemplateContainerUid` workflow command** — `Input::WorkflowCommand::EditTemplateContainerUid`,
|
|
435
456
|
registered on the command bus. Unlike its `editTemplate*` siblings it raises on a nil value rather
|
|
436
457
|
than emitting an empty command (the schema argument is `String!`) and validates the backend's
|
|
@@ -458,7 +479,7 @@ All 568 `lib/` files are unchanged; nothing outside `lib/` was ever loaded at ru
|
|
|
458
479
|
diff (adds/removes/changes/reorders, bookkeeping noise hidden by default, nil≡empty-container
|
|
459
480
|
lenience for document-age drift). Detects a foreign id-space and points at
|
|
460
481
|
`Diff::CrossObjectDiff` instead of emitting a misleading add/remove-everything report.
|
|
461
|
-
- Scoping project
|
|
482
|
+
- Scoping project the repo's internal docs — coordination of the data
|
|
462
483
|
import/extract/migration tool-set (legacy imports, template and register metadata table
|
|
463
484
|
definitions, BI warehouse extracts, spreadsheet and back-end imports, register-to-register and
|
|
464
485
|
org-to-org migrations, register-revamp mapping and readiness reporting). Capability map C1-C8,
|
|
@@ -525,7 +546,7 @@ The web "System Access Logs" page and page "history changelog" are driven by
|
|
|
525
546
|
|
|
526
547
|
- `ecoportal-api` dependency floor raised to `0.10.17`: inherits the `WithRetry` fix that
|
|
527
548
|
makes `HTTP::TimeoutError` (connect/read/write timeouts) retryable — previously a single
|
|
528
|
-
transient timeout killed whole batch loops (live-confirmed on
|
|
549
|
+
transient timeout killed whole batch loops (live-confirmed on a customer org, 2026-07-30).
|
|
529
550
|
- **`graphlient` dependency now points at the published `0.9.0` release** instead of the fork's
|
|
530
551
|
frozen git branch (`rellampec/graphlient@pre-v0.0.9`). `0.9.0` ships the same DSL/directive
|
|
531
552
|
work the gem already relied on (`#115` `to_query_string`/`spread`, `#116` directives DSL,
|
|
@@ -648,7 +669,7 @@ The web "System Access Logs" page and page "history changelog" are driven by
|
|
|
648
669
|
`people{id}` nodes on both sides), not the raw `peopleIds` key — the backend can return
|
|
649
670
|
`peopleIds: null` on reads while still populating `people`/`cachedPeople`, so restating an
|
|
650
671
|
already-attached person id no longer registers as a change. Live-confirmed 2026-07-16
|
|
651
|
-
(
|
|
672
|
+
(a customer dry-run reported "Updated 6/6" for a no-op). Mirrors the `CrossReference`
|
|
652
673
|
fix for the identical disease; `as_input` now serialises the fallback-aware `people_ids`
|
|
653
674
|
reader instead of the raw doc key.
|
|
654
675
|
- `ContractorEntities` field: the reader read the staged write key (`contractors`), which read
|
|
@@ -720,7 +741,7 @@ The web "System Access Logs" page and page "history changelog" are driven by
|
|
|
720
741
|
**Migrate to:** `editTemplateBasicSettings` (name/icon/settings/counter/tags/folders/creator
|
|
721
742
|
perms), `editTemplateDescriptions` (`description`), `editTemplateCreatorPermissions` (creator
|
|
722
743
|
perms). The old `editPage` `addOtherTags`/`removeOtherTags` keys have no `editTemplate*`
|
|
723
|
-
equivalent (dropped from schema). No downstream callers existed (eco-helpers /
|
|
744
|
+
equivalent (dropped from schema). No downstream callers existed (eco-helpers / internal script repos /
|
|
724
745
|
gem swept) so the removal is clean. See DECISIONS.md in the workflow-space project.
|
|
725
746
|
- **`Mutation::SmartFill::Generate` / `Mutation::SmartFill::SubmitFeedback` and
|
|
726
747
|
`Builder::Page#generate_smart_fill` / `#submit_smart_fill_feedback`** (breaking, but dead
|
|
@@ -742,13 +763,13 @@ The web "System Access Logs" page and page "history changelog" are driven by
|
|
|
742
763
|
to measure coverage — only the QUESTION carries one; its satellites (comment, image, document,
|
|
743
764
|
recommended action) do not and are not expected to. The denominator is workbook questions
|
|
744
765
|
(`question_ref`), never the field count; measuring against all fields yields a meaningless ~16%.
|
|
745
|
-
-
|
|
766
|
+
- the repo's internal docs — the authoritative
|
|
746
767
|
workbook-to-template contract recovered verbatim from the 2026-08-08 session transcript:
|
|
747
768
|
`QuestionSetReference` → template_container_id (UI "UNIQUE IDENTIFIER"), `QuestionReference` →
|
|
748
769
|
field `description` (CONFIRMED), `QuestionInformation` → field tooltip (strip HTML entities),
|
|
749
770
|
scores ignored, section-vs-stage left ambiguous, plus the template-pairing procedure and the
|
|
750
771
|
DEV-site targeting note.
|
|
751
|
-
-
|
|
772
|
+
- the repo's internal docs — past sessions are greppable JSONL
|
|
752
773
|
transcripts on disk (35 sessions, 85 MB); search them before asking the developer something he may
|
|
753
774
|
already have answered.
|
|
754
775
|
|
|
@@ -876,7 +897,7 @@ signed-off future decision.)
|
|
|
876
897
|
(`external_id`/`id`/`state`) — a spurious path produced term `membranes.external_id.external_id`
|
|
877
898
|
→ 0 results (silent miss → dup-on-upsert). Register FIELD keys still get the nested path.
|
|
878
899
|
- Verified against the backend filter definitions; catalogued in
|
|
879
|
-
|
|
900
|
+
the repo's internal docs.
|
|
880
901
|
|
|
881
902
|
### Added
|
|
882
903
|
|
|
@@ -948,7 +969,7 @@ shapes checked against the live schema dump); the live UAT→PROD round trip is
|
|
|
948
969
|
longer exists (fragments are a registry now) → `uninitialized constant … Fragment::… (NameError)` at
|
|
949
970
|
render time. Now `spread :Action` / `spread :ContractorEntity`, matching the already-migrated queries.
|
|
950
971
|
(The sibling breakage in eco-helpers' location-command optimizations is fixed in eco-helpers 3.2.17;
|
|
951
|
-
it crashed
|
|
972
|
+
it crashed a customer's live locations sync.)
|
|
952
973
|
- **Kickstand workflow mutations — bare `DateTime` selection.** `Kickstand::{Start,Stop,Fail}Workflow`
|
|
953
974
|
selected `startedAt`/`stoppedAt`/`failedAt` bare → "Field must have selections". Now
|
|
954
975
|
`{ dateTime timeZone }` (same class as the 1.3.10 LocationStructure fix).
|
|
@@ -976,7 +997,7 @@ shapes checked against the live schema dump); the live UAT→PROD round trip is
|
|
|
976
997
|
|
|
977
998
|
## [1.3.10] - 2026-07-03
|
|
978
999
|
|
|
979
|
-
Hotfix (backwards-compatible). Resolves a live failure on
|
|
1000
|
+
Hotfix (backwards-compatible). Resolves a live failure on a customer's users sync.
|
|
980
1001
|
|
|
981
1002
|
### Fixed
|
|
982
1003
|
|
|
@@ -15,7 +15,7 @@ module Ecoportal::API::Common::GraphQL::Model::Diffable
|
|
|
15
15
|
# `CollectionModel` — neither is a `GraphQL::Model`, so the re-add never happens and
|
|
16
16
|
# the array change becomes **invisible to `as_update`** (scalar `passthrough` fields
|
|
17
17
|
# are unaffected). This is the systemic "array/leaf fields don't diff" root cause
|
|
18
|
-
# (see
|
|
18
|
+
# (see the repo's internal docs §3.1).
|
|
19
19
|
#
|
|
20
20
|
# This service fixes it for leaf models by:
|
|
21
21
|
# 1. keeping cascaded keys in the flat classic diff (`doc_with_non_cascaded_attributes`
|
|
@@ -31,7 +31,7 @@ module Ecoportal::API::GraphQL::Base::Page
|
|
|
31
31
|
|
|
32
32
|
# Find first field matching label (case-insensitive). Optional type: restricts to
|
|
33
33
|
# that field type first (v2 compat: components.get_by_name(name, type:) — used by
|
|
34
|
-
#
|
|
34
|
+
# a customer cutover use case which calls it directly, not via OozeRedirect).
|
|
35
35
|
def get_by_name(label, type: nil)
|
|
36
36
|
pool = type ? get_by_type(type) : @fields
|
|
37
37
|
pool.find { |f| f.label.to_s.downcase == label.to_s.downcase }
|
|
@@ -18,7 +18,7 @@ module Ecoportal
|
|
|
18
18
|
# tag_filter passed through (same ES backend, same format)
|
|
19
19
|
# register_filter passed through
|
|
20
20
|
# and_filter / or_filter passed through
|
|
21
|
-
# Operation/param shapes per .
|
|
21
|
+
# Operation/param shapes per the repo's internal docs.
|
|
22
22
|
class FilterTranslator
|
|
23
23
|
class << self
|
|
24
24
|
def to_graphql(filter)
|
|
@@ -99,7 +99,7 @@ module Ecoportal
|
|
|
99
99
|
# `templateContainerUid` is the SERIES key: many versions may carry the same uid,
|
|
100
100
|
# but only one may be published (`active: true`) per organization at a time —
|
|
101
101
|
# publishing another with the same uid unpublishes the incumbent. See
|
|
102
|
-
#
|
|
102
|
+
# the repo's internal docs.
|
|
103
103
|
template @skip(if: $only_content) {
|
|
104
104
|
templateContainerUid
|
|
105
105
|
active
|
|
@@ -137,7 +137,7 @@ module Ecoportal
|
|
|
137
137
|
# per-type members carry no description, so `updatePage` cannot set it.
|
|
138
138
|
#
|
|
139
139
|
# Integrations use it as a pseudo external-id on fields (we do so on templates;
|
|
140
|
-
#
|
|
140
|
+
# customers do so on page instances — confirmed working on instances with a
|
|
141
141
|
# non-superuser service account, 2026-07-31). Fetched by default so those
|
|
142
142
|
# integrations can read it back.
|
|
143
143
|
description @skip(if: $only_content)
|
|
@@ -58,13 +58,11 @@ module Ecoportal
|
|
|
58
58
|
pageCanListDrafts { ...AuthorizationResult }
|
|
59
59
|
pageCanRestore { ...AuthorizationResult }
|
|
60
60
|
pageCanUseDrafts { ...AuthorizationResult }
|
|
61
|
-
pageSmartAssistantCanChat { ...AuthorizationResult }
|
|
62
61
|
personSchemaCanAccessManager { ...AuthorizationResult }
|
|
63
62
|
publicTemplatesCanCopyLink { ...AuthorizationResult }
|
|
64
63
|
publicTemplatesCanIndex { ...AuthorizationResult }
|
|
65
64
|
publicTemplatesCanListEntries { ...AuthorizationResult }
|
|
66
65
|
publicTemplatesCanManage { ...AuthorizationResult }
|
|
67
|
-
registerAssistantCanChat { ...AuthorizationResult }
|
|
68
66
|
registerCanAccessRegisterTools { ...AuthorizationResult }
|
|
69
67
|
registerCanCreate { ...AuthorizationResult }
|
|
70
68
|
registerCanLimitTemplates { ...AuthorizationResult }
|
|
@@ -70,8 +70,8 @@ module Ecoportal
|
|
|
70
70
|
# Page tasks (and the people-field permissions scoped to them) apply to ONE
|
|
71
71
|
# stage; without a stageId the server cannot route the submit to the stage the
|
|
72
72
|
# work was done on. Fail loudly here rather than silently omit stageId (the
|
|
73
|
-
# nil-guard in build_input would otherwise drop it — the exact bug that let
|
|
74
|
-
#
|
|
73
|
+
# nil-guard in build_input would otherwise drop it — the exact bug that let a
|
|
74
|
+
# customer submission go out stage-less). A plain field update or publish
|
|
75
75
|
# needs no stage and is unaffected.
|
|
76
76
|
def require_stage!(stage_id, submit, task)
|
|
77
77
|
return unless stage_id.nil?
|
|
@@ -96,7 +96,7 @@ module Ecoportal
|
|
|
96
96
|
# A register FIELD key carries a `<type>.<hash>` shape (e.g. 'date.zab1bddc3');
|
|
97
97
|
# system/top-level keys (created_at, external_id, state) have no such prefix.
|
|
98
98
|
# Field filters need the nested `membranes.<type>` path — see
|
|
99
|
-
# .
|
|
99
|
+
# the repo's internal docs.
|
|
100
100
|
# ---------------------------------------------------------------------------
|
|
101
101
|
module MembranePath
|
|
102
102
|
module_function
|
|
@@ -6,7 +6,7 @@ module Ecoportal
|
|
|
6
6
|
# `WorkflowEditTemplateContainerUidInput { templateContainerUid: String! }`.
|
|
7
7
|
#
|
|
8
8
|
# Sets the template's CROSS-VERSION identity key. Semantics (verified against the
|
|
9
|
-
# backend on 2026-07-31 — see
|
|
9
|
+
# backend on 2026-07-31 — see the repo's internal docs):
|
|
10
10
|
#
|
|
11
11
|
# - Format `/\A[a-zA-Z0-9\-_.]{3,20}\z/` — org-scoped, human-authored.
|
|
12
12
|
# - Many versions of a template may share one uid, but only ONE may be published
|
|
@@ -17,7 +17,7 @@ module Ecoportal
|
|
|
17
17
|
# included in a copy (`include`) and whether the choice is locked against per-copy
|
|
18
18
|
# override (`enforce`). `enforce` is the least certain of these.
|
|
19
19
|
# Confirm against platform behaviour before relying on any of it; see
|
|
20
|
-
#
|
|
20
|
+
# the repo's internal docs.
|
|
21
21
|
module ManageCopyPageConfiguration
|
|
22
22
|
SCHEMA_VERSION = '20260819'.freeze
|
|
23
23
|
VALID_KEYS = %i[overridePageCreatorPermissions autoIncludeNewContent inclusionSettingsChanges].freeze
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Ecoportal
|
|
2
|
+
module API
|
|
3
|
+
class GraphQL
|
|
4
|
+
module Input
|
|
5
|
+
class WorkflowCommand
|
|
6
|
+
# `WorkflowMoveSectionToStageInput` (20260929) -- moves an existing section from one
|
|
7
|
+
# stage to another, optionally placed relative to an anchor section. Unlike
|
|
8
|
+
# `reorderSection` (same stage), the source and target stages are both required.
|
|
9
|
+
module MoveSectionToStage
|
|
10
|
+
SCHEMA_VERSION = '20260929'.freeze
|
|
11
|
+
VALID_KEYS = %i[sourceStageId targetStageId sectionId anchorId anchorPosition].freeze
|
|
12
|
+
ANCHOR_POSITIONS = AddViewableField::ANCHOR_POSITIONS
|
|
13
|
+
|
|
14
|
+
def self.build(source_stage_id:, target_stage_id:, section_id:, **kwargs)
|
|
15
|
+
position = kwargs[:anchorPosition]
|
|
16
|
+
unless position.nil? || ANCHOR_POSITIONS.include?(position.to_s)
|
|
17
|
+
raise ArgumentError,
|
|
18
|
+
"Invalid anchorPosition #{position.inspect}: " \
|
|
19
|
+
"expected one of #{ANCHOR_POSITIONS.join(', ')}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
{
|
|
23
|
+
sourceStageId: source_stage_id,
|
|
24
|
+
targetStageId: target_stage_id,
|
|
25
|
+
sectionId: section_id
|
|
26
|
+
}.merge(kwargs.slice(:anchorId, :anchorPosition).compact)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -43,6 +43,7 @@ module Ecoportal
|
|
|
43
43
|
collapseSection: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::CollapseSection',
|
|
44
44
|
expandSection: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::ExpandSection',
|
|
45
45
|
reorderSection: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::ReorderSection',
|
|
46
|
+
moveSectionToStage: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::MoveSectionToStage',
|
|
46
47
|
# Task
|
|
47
48
|
addTask: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::AddTask',
|
|
48
49
|
removeTask: 'Ecoportal::API::GraphQL::Input::WorkflowCommand::RemoveTask',
|
|
@@ -275,6 +276,7 @@ require_relative 'workflow_command/edit_linked_helper'
|
|
|
275
276
|
require_relative 'workflow_command/remove_linked_helper'
|
|
276
277
|
require_relative 'workflow_command/add_viewable_field'
|
|
277
278
|
require_relative 'workflow_command/move_viewable_field'
|
|
279
|
+
require_relative 'workflow_command/move_section_to_stage'
|
|
278
280
|
require_relative 'workflow_command/remove_viewable_field'
|
|
279
281
|
require_relative 'workflow_command/field_config/action_list'
|
|
280
282
|
require_relative 'workflow_command/field_config/contractor_entities'
|
|
@@ -155,7 +155,7 @@ module Ecoportal
|
|
|
155
155
|
# location `graphql-client` deliberately sets via
|
|
156
156
|
# `set_backtrace(["#{filename}:#{line}"])`. With that gone there was no other
|
|
157
157
|
# way to see which query blew up. (Tracked upstream; see
|
|
158
|
-
#
|
|
158
|
+
# the repo's internal docs.)
|
|
159
159
|
#
|
|
160
160
|
# But the location was never actually destroyed. Ruby populates `.cause`
|
|
161
161
|
# automatically when you raise inside a rescue, so the original error — with the
|
|
@@ -108,6 +108,9 @@ module Ecoportal
|
|
|
108
108
|
klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
|
|
109
109
|
embeds_one :pageCanUseDrafts,
|
|
110
110
|
klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
|
|
111
|
+
# DEPRECATED (20260929): removed from the live schema by the smart-assistant
|
|
112
|
+
# consolidation; no longer selected by Fragment::Permissions, so always nil. Kept so
|
|
113
|
+
# callers get nil instead of NoMethodError.
|
|
111
114
|
embeds_one :pageSmartAssistantCanChat,
|
|
112
115
|
klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
|
|
113
116
|
embeds_one :personSchemaCanAccessManager,
|
|
@@ -120,6 +123,9 @@ module Ecoportal
|
|
|
120
123
|
klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
|
|
121
124
|
embeds_one :publicTemplatesCanManage,
|
|
122
125
|
klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
|
|
126
|
+
# DEPRECATED (20260929): removed from the live schema by the smart-assistant
|
|
127
|
+
# consolidation; no longer selected by Fragment::Permissions, so always nil. Kept so
|
|
128
|
+
# callers get nil instead of NoMethodError.
|
|
123
129
|
embeds_one :registerAssistantCanChat,
|
|
124
130
|
klass: "Ecoportal::API::GraphQL::Model::AuthorizationResult", nullable: true
|
|
125
131
|
embeds_one :registerCanAccessRegisterTools,
|
|
@@ -4,7 +4,7 @@ module Ecoportal
|
|
|
4
4
|
module Query
|
|
5
5
|
# DB-backed full-data org search — returns PageUnion nodes with patchVer and field IDs.
|
|
6
6
|
# Required pre-update fetch: always use this (not RegisterPreviewPages) before updatePage.
|
|
7
|
-
# See
|
|
7
|
+
# See the repo's internal docs — "The Required Pattern: Find Before Mutate".
|
|
8
8
|
class Pages < Logic::QueryConnection
|
|
9
9
|
field_name :pages
|
|
10
10
|
# Response nests under currentOrganization.pages; needed when instantiated
|
|
@@ -3,7 +3,7 @@ module Ecoportal
|
|
|
3
3
|
class GraphQL
|
|
4
4
|
module Query
|
|
5
5
|
# Fetches the org-level permission set: currentOrganization.permissions.
|
|
6
|
-
# Returns a Model::Permissions whose ~
|
|
6
|
+
# Returns a Model::Permissions whose ~81 canXXX fields are AuthorizationResult.
|
|
7
7
|
# Selects the :Permissions fragment (which spreads :AuthorizationResult per field).
|
|
8
8
|
class Permissions < Logic::Query
|
|
9
9
|
field_name :permissions
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ecoportal-api-graphql
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.2.
|
|
4
|
+
version: 2.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Oscar Segura
|
|
@@ -534,6 +534,7 @@ files:
|
|
|
534
534
|
- lib/ecoportal/api/graphql/input/workflow_command/field_config/table.rb
|
|
535
535
|
- lib/ecoportal/api/graphql/input/workflow_command/manage_copy_page_configuration.rb
|
|
536
536
|
- lib/ecoportal/api/graphql/input/workflow_command/move_field.rb
|
|
537
|
+
- lib/ecoportal/api/graphql/input/workflow_command/move_section_to_stage.rb
|
|
537
538
|
- lib/ecoportal/api/graphql/input/workflow_command/move_stage.rb
|
|
538
539
|
- lib/ecoportal/api/graphql/input/workflow_command/move_viewable_field.rb
|
|
539
540
|
- lib/ecoportal/api/graphql/input/workflow_command/remove_action_tag.rb
|