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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 371133ecd295f75aacb3e34c85f4cc93c5561cc0b12452091fb19d73fb32adda
4
- data.tar.gz: 422e949c1544c1d94dc0bd3f7f2825d5a747449976cda7eef04c51ca9da4d523
3
+ metadata.gz: 128e83d1aa8d0fa5b9e4ce95f8bbd5f8bd4f219ea7d7a94dd18ec31225ac3ce9
4
+ data.tar.gz: 7d79138b320e6ba09221bd79a4c341ef9dc039f4ccf6923567f3f4b36f657c27
5
5
  SHA512:
6
- metadata.gz: 9627606e555d1fcbff9bede5d611d34fc2274c4566bae93b67e9c1821a730bbef6b8831f46061e1557f7123302c70a022af77228c2c69297a87a46bb0ee2db33
7
- data.tar.gz: 291a7b865d87ec744bd23d97916808105a8cad7bad525af5862d19f7c21e367760930aa49e67af5991a181ab406cadc298b5a33ca354677fe0cc27d772ce4718
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 the 18 M&S templates -- refusal set matches the Python exactly.
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 the 18 M&S templates: **`P8 GATE: PASS`**,
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 the M&S pack tells customers to perform, which until now no tool
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/mns/cli.rb`
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/mns/collection.rb` -- a pure-Ruby, stdlib-only read interface over the MnS Postman "ALL
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/mns/collection_sync_spec.rb` pins the webhook-admin and build/update-page
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/mns/README.md`.
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-mns-18-templates.md`.
251
+ `tools/template_yaml/reviews/2026-08-09-<customer>-18-templates.md`.
230
252
 
231
- - **`tools/mns/cli.rb`** -- a Ruby CLI that creates/lists/destroys the M&S webhook
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 the M&S UAT org, EU
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/mns/webhooks.rb` (`MnsWebhooks::Documents`) as pure
238
- functions, spec'd in `spec/tools/mns/webhooks_spec.rb` with no network involved.
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 `.ai-assistance/code/template_change_log.md`.
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 M&S dump set: 2,714 fields, ids and ordering match the
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 (`6a4c4f12316577006e210b7a`..`..b7f`), where
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
- M&S template without affecting counts. The JSON export carries identical data with plain hex
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 M&S JSON dump set, including the 6
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
- (`6a4c4f12316577006e210b7a`..`..b7f`), which load and validate correctly.
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`, `integration-training`, `multi_org_api` and
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 `.ai-assistance/`
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 `.ai-assistance/code/ecoPortal_architecture/02_data_model.md`.
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 `.ai-assistance/projects/data-toolset/` — coordination of the data
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 Farmers, 2026-07-30).
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
- (act-gov TOOCS dry-run reported "Updated 6/6" for a no-op). Mirrors the `CrossReference`
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 / multi_org_api /
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
- - `.ai-assistance/projects/mns-template-lifecycle/WORKBOOK-FIELD-MAPPING.md` — the authoritative
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
- - `.ai-assistance/conventions/recovering-prior-context.md` — past sessions are greppable JSONL
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
- `.ai-assistance/code/filter_contract_matrix.md`.
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 the live act-gov locations sync.)
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 the Turners & Growers users sync.
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 `.ai-assistance/code/model_input_mapping/SYNTHESIS.md` §3.1).
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
- # the farmers cutover use case which calls it directly, not via OozeRedirect).
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 .ai-assistance/code/search_filters.md.
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
- # `.ai-assistance/code/ecoPortal_architecture/02_data_model.md`.
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
- # M&S do so on page instances — confirmed working on instances with a
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 an
74
- # act-gov TOOCS submit go out stage-less). A plain field update or publish
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
- # .ai-assistance/code/filter_contract_matrix.md.
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 `.ai-assistance/code/ecoPortal_architecture/02_data_model.md`):
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
- # `.ai-assistance/code/ecoPortal_architecture/10_forces_workflow_builder.md`.
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
- # `.ai-assistance/code/refactoring/opportunities.md`.)
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 .ai-assistance/code/search_filters.md — "The Required Pattern: Find Before Mutate".
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 ~83 canXXX fields are AuthorizationResult.
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
@@ -1,5 +1,5 @@
1
1
  module Ecoportal
2
2
  module API
3
- GRAPQL_VERSION = '2.2.0'.freeze
3
+ GRAPQL_VERSION = '2.2.1'.freeze
4
4
  end
5
5
  end
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.0
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