Skip to content

resource/pingone_davinci_flow: prepare exporter for multi-outcome node routing - #127

Merged
samir-gandhi merged 6 commits into
mainfrom
polaris/davinci-forms-update
Jul 20, 2026
Merged

resource/pingone_davinci_flow: prepare exporter for multi-outcome node routing#127
samir-gandhi merged 6 commits into
mainfrom
polaris/davinci-forms-update

Conversation

@samir-gandhi

@samir-gandhi samir-gandhi commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • DaVinci flows with multi-outcome nodes (e.g. a PingOne Forms showForm node with "Save" and "Resend" exit paths) currently break when exported to HCL and re-applied, because the node's outcomes array is dropped on the round trip while edges referencing those outcome IDs (multi_value_source_id) are preserved — the applied flow ends up routing to outcome IDs that don't exist.
  • Root-caused this to a three-layer gap: the OpenAPI spec that generates the PingOne Go SDK had no outcomes field on DaVinci flow node data, so it generated neither a typed SDK field nor a Terraform provider schema attribute. Update: the full upstream chain has now shippedpingone-go-client v0.12.0 added a typed Outcomes field, and terraform-provider-pingone merged schema support in PR #1345 (merged 2026-07-16, not yet in a tagged release). This PR now includes the SDK bump to pick up the typed field.
  • Upstream tracking: CDI-1370 (OpenAPI spec, resolved) → pingone-go-client#86 (SDK, resolved in v0.12.0) → terraform-provider-pingone#1342 (provider, merged to main, awaiting a tagged release).

Upstream fix verified — all three follow-up items confirmed correct

The three items originally flagged for re-verification once the provider shipped support have all been checked against the real merged code:

  1. Field naming/casing — ✅ confirmed. pingone-go-client v0.12.0 adds Outcomes []DaVinciFlowGraphDataResponseElementsNodeDataOutcome — exactly the PascalCase name this PR's source_path: Outcomes assumed.
  2. List vs Set — ✅ confirmed. The provider's generated schema uses schema.ListNestedAttribute (types.ListType), matching this PR's type: list.
  3. terraform_name alignment — ✅ confirmed. The provider's attribute is literally named outcomes, matching this PR's terraform_name: outcomes.

No changes were needed to flow.yaml's outcomes block. The only change required was bumping go.mod to pingone-go-client v0.12.0 (this commit) so the AdditionalProperties fallback in internal/core/processor.go goes dormant for this field and resolution goes through the normal named-field path instead — verified directly: unmarshaling a raw JSON payload with an outcomes key now populates the typed Outcomes field, not AdditionalProperties. The existing test (davinci_flow_outcomes_test.go) was updated to construct the typed field directly rather than the no-longer-representative AdditionalProperties stuffing it used before.

Still blocking end-to-end: terraform-provider-pingone's fix (PR #1345) is merged to main but not yet in a tagged release (latest is still v1.20.0). Exporting a flow with multi-outcome nodes today will produce HCL the currently released provider version cannot apply — this will resolve itself once a new provider version ships, with no further changes needed here.

Changes

  • Added a generic AdditionalProperties fallback to the processor's field resolution (internal/core/processor.go): when a YAML attribute's source_path doesn't match a named SDK struct field, resolution now falls back to a lookup in that struct's AdditionalProperties catch-all (exact key, then lower-first-letter camelCase). This isn't outcomes-specific — it benefits any current or future SDK field that lags behind its JSON shape, with zero custom Go code required per the repo's schema-driven architecture.
  • Added the outcomes attribute to definitions/pingone/davinci/flow.yaml under node data (type: list, nested id/result/label), which resolves via the fallback above.
  • Both changes are additive and inert on their own: nodes without outcomes continue to export unchanged, and no HCL currently generated changes shape, since the Terraform provider doesn't yet accept the attribute.
  • Added go.mod/go.sum bump to pingone-go-client v0.12.0 to pick up the typed Outcomes field once it existed upstream (see verification section above).

Test plan

  • A struct with no matching named field but a populated AdditionalProperties entry resolves via the fallback — Verified by unit tests in internal/core/processor_test.go
  • Regression guards: no-AdditionalProperties-field structs, nil maps, and absent keys all behave identically to pre-change code — Verified by unit tests in internal/core/processor_test.go
  • The real flow.yaml definition, loaded via the schema registry, correctly renders an outcomes block for a node that has it and omits the attribute for a node that doesn't, in both HCL and the processor's intermediate representation — Verified by internal/core/davinci_flow_outcomes_test.go
  • Full existing test suite, go vet, and validate-definitions pass with no regressions — Verified by make test, make vet, go run ./tools/validate-definitions definitions/

🤖 Generated with Claude Code

findFieldByPath now falls back to a struct's AdditionalProperties map
(exact key, then lower-first-letter camelCase) when a named-field lookup
misses, so YAML attributes can source fields the SDK hasn't typed yet
(e.g. DaVinci node data outcomes) with zero custom Go code. Every call
site (processOneAttribute, convertSliceToMap, processTypeDiscriminatedBlock)
inherits this for free since they all route through findFieldByPath.
…hema

Declares outcomes (list of id/result/label) under GraphData.Elements.Nodes.Data
in flow.yaml, resolved via the AdditionalProperties fallback added in the
previous commit since the SDK has no typed Outcomes field yet. Zero formatter
changes needed -- list-with-nested_attributes rendering already generic.
Inert until terraform-provider-pingone adds provider-side schema support for
multi-outcome node routing; groundwork so the exporter activates the moment
the provider ships it.

Adds processor + HCL formatter tests driven by the real flow.yaml definition
(via schema.Registry) rather than a synthetic schema, to catch drift between
the fallback and the actual attribute declaration.
@github-actions

Copy link
Copy Markdown

Regression Test Results

Matrix Entry Status Breaking Acceptable
default-hcl ✅ PASS 0 0
default-tfjson ✅ PASS 0 0
hcl-include-all ✅ PASS 0 0
hcl-skip-deps ✅ PASS 0 0
tfjson-skip-deps ✅ PASS 0 0

✅ No regressions detected

All export configurations produced compatible output.


Generated by regression workflow • View run

…ps outcomes

Points the outcomes block's comment at the PR description, which lists what
to re-check once terraform-provider-pingone accepts the attribute: field
naming/casing on the regenerated SDK struct, list vs set on the provider
schema, and terraform_name alignment.
@github-actions

Copy link
Copy Markdown

Regression Test Results

Matrix Entry Status Breaking Acceptable
default-hcl ✅ PASS 0 0
default-tfjson ✅ PASS 0 0
hcl-include-all ✅ PASS 0 0
hcl-skip-deps ✅ PASS 0 0
tfjson-skip-deps ✅ PASS 0 0

✅ No regressions detected

All export configurations produced compatible output.


Generated by regression workflow • View run

…utcomes field

terraform-provider-pingone#1342 and pingone-go-client#86 merged the
outcomes field upstream (CDI-1370's spec fix landed). pingone-go-client
v0.12.0 now types DaVinciFlowGraphDataResponseElementsNodeData.Outcomes
as a named field, so the AdditionalProperties fallback added for this
attribute goes dormant -- resolution goes through the normal named-field
path in findFieldByPath, exactly as anticipated. Updated
davinci_flow_outcomes_test.go to construct the typed field directly
(matching how a real API response now unmarshals) instead of stuffing
outcomes into AdditionalProperties, which no longer reflects reality.

The terraform-provider-pingone fix (PR #1345) is merged to main but not
yet in a tagged release, so applying HCL with an outcomes block still
fails against the current provider release -- noted in the changelog
entry.
The follow-up-verification framing is stale now that
terraform-provider-pingone#1342 / pingone-go-client#86 have both
resolved. Points at PR #127's description for the current release
status instead of restating open questions that are now answered.
@github-actions

Copy link
Copy Markdown

Regression Test Results

Matrix Entry Status Breaking Acceptable
hcl-skip-deps ✅ PASS 0 0
tfjson-skip-deps ✅ PASS 0 0

✅ No regressions detected

All export configurations produced compatible output.


Generated by regression workflow • View run

@github-actions

Copy link
Copy Markdown

Regression Test Results

Matrix Entry Status Breaking Acceptable
default-hcl ✅ PASS 0 0
default-tfjson ✅ PASS 0 0
hcl-include-all ✅ PASS 0 0
hcl-skip-deps ✅ PASS 0 0
tfjson-skip-deps ✅ PASS 0 0

✅ No regressions detected

All export configurations produced compatible output.


Generated by regression workflow • View run

Rephrase to assume the terraform-provider-pingone release containing
outcomes support (terraform-provider-pingone#1342, merged via #1345)
will be out by the time this PR ships -- this repo is holding merge
until that release lands.
@github-actions

Copy link
Copy Markdown

Regression Test Results

Matrix Entry Status Breaking Acceptable
default-hcl ✅ PASS 0 0
default-tfjson ✅ PASS 0 0
hcl-include-all ✅ PASS 0 0
hcl-skip-deps ✅ PASS 0 0
tfjson-skip-deps ✅ PASS 0 0

✅ No regressions detected

All export configurations produced compatible output.


Generated by regression workflow • View run

@samir-gandhi
samir-gandhi merged commit 1aef79a into main Jul 20, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant