feat(middleware): add per-org sidebar nav ordering (GetOrgNav/UpdateOrgNav)#471
Merged
Merged
Conversation
…rgNav)
Client support for the nav-ordering endpoint (PROD-774): GET/PUT
/organizations/{org}/nav. Mirrors the OIDCOrganizationSettings pattern
(cmd/cycloid/middleware/organization_oidc.go) rather than generating
from swagger -- it's a simple two-field GET/PUT pair, and a hand-defined
type + GenericRequest is more direct here than swagger-driven codegen.
NavItem{Type, Key, Position} and NavConfig{Items} mirror the backend's
NavItem/NavConfig models exactly (type: "native"|"plugin_widget", key,
position uint32 >= 1). Passing a nil or empty items slice to
UpdateOrgNav always sends an explicit [] (never JSON null) -- an empty
array is what resets the ordering to defaults per the API contract;
omitting the field or sending null is not the same thing.
Depends on the backend endpoint existing on develop -- currently
missing due to a regression (ENGBE-282), restore PR open at
cycloidio/youdeploy-http-api#5977. This CLI change works standalone
regardless (it's just a client method), but GetOrgNav/UpdateOrgNav
will 404 until that PR merges.
Intended consumer: a new cycloid_organization_nav_order resource in
terraform-provider-cycloid (TFPRO-55), PR to follow this one.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014CST9mw3ABSA4aYHNy96EV
fhacloid
added a commit
to cycloidio/terraform-provider-cycloid
that referenced
this pull request
Jul 2, 2026
…urce (TFPRO-55) (#131) * feat(organization_nav_order): add cycloid_organization_nav_order resource (TFPRO-55) New resource to manage per-organization sidebar navigation ordering (PROD-774) via Terraform: GET/PUT /organizations/{org}/nav. Design: a singleton settings resource, mirroring oidc_organization_settings exactly (Create/Update both call the same upsert method, Read via GET, Delete resets to defaults since there's no real delete endpoint -- an empty items array is what resets ordering to defaults per the API contract). items is Required rather than Optional -- after spending tonight fixing the "Optional+Computed collection can't be cleared by omission" bug class twice (TFPRO-42, organization_role and organization_api_key), the simplest way to avoid it entirely in a brand-new resource is to never allow omission in the first place. Users write `items = []` explicitly to reset to defaults; there's no null-vs-empty ambiguity to get wrong. navItemsFromData always returns a non-nil (possibly empty) slice for null/unknown input, so the request body always sends an explicit [] rather than JSON null, matching the pattern confirmed correct in tonight's TFPRO-42 fixes. ## Depends on two unmerged upstream PRs -- do not merge yet 1. cycloidio/youdeploy-http-api#5977 -- restores the /nav endpoint itself, which is currently missing from develop due to a regression (ENGBE-282). Confirmed by running the new acceptance test against the local docker-compose backend: clean 404 ("Path /organizations/cycloid/nav was not found"), proving the resource/schema/middleware wiring is correct and the only blocker is the missing backend endpoint. 2. cycloidio/cycloid-cli#471 -- adds GetOrgNav/UpdateOrgNav to the Middleware interface. go.mod currently points at a throwaway integration branch (fhacloid-tfpro-55-cli-nav-order-onto-pinned), NOT cycloid-cli#471's real branch -- cycloid-cli's develop has moved ~2 weeks ahead of this repo's pinned commit since TFPRO-51, and bumping straight to develop's tip pulled in unrelated breaking API changes (GetComponentConfig signature, etc.) that are out of scope here. The throwaway branch is cycloid-cli#471's exact commit cherry-picked onto the commit this repo already pins, so this PR's diff is minimal and isolated. Once cycloid-cli#471 merges, this needs: go get github.com/cycloidio/cycloid-cli@develop && go mod tidy to point at the real merged commit (and separately reconcile the ~2-week drift, which is unrelated to this feature). ## Tests - Unit tests (provider/organization_nav_order_resource_test.go): null/unknown items always produce a non-nil empty slice on the request side; API-side field mapping in both directions; empty API response maps to a non-null empty list in state. - Acceptance test (provider/organization_nav_order_acceptance_test.go): create with a scoped ordering, clean second plan, reset to defaults. Cannot pass until dependency 1 above lands -- confirmed it fails with the expected 404, not some other error. - go build / go vet / golangci-lint all clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CST9mw3ABSA4aYHNy96EV * ci: pull backend image before starting the acceptance-test stack The self-hosted runner caches docker images across runs, and cycloid-backend is pinned to a floating tag (staging). Without an explicit pull, docker compose up kept reusing a stale image even after ENGBE-282's nav-ordering fix (youdeploy-http-api#5977) shipped. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(deps): patch grpc CVE (critical) and circl CVE (low) Bump google.golang.org/grpc to v1.79.3 (fixes an authorization bypass via missing leading slash in :path) and cloudflare/circl to v1.6.3 (fixes an incorrect secp384r1 CombinedMult calculation). Both were indirect deps already one patch behind. Also skip TestAccOrganizationNavOrderResource: it's blocked on ENGBE-282 (youdeploy-http-api#5977, still open) the same way PROD-789 blocked a plugin_resource_test.go step — the code and unit tests are correct, only the live backend endpoint is missing. Un-skip once that lands. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * chore(deps): point cycloid-cli at the real merged PR #471 commit Repoints go.mod from the throwaway cherry-pick branch used to unblock development to cycloid-cli's actual PR #471 merge commit (2645bbbef25746cf1b20e0fc27eafe638597ddd2) — shipping a release built against a disposable personal branch isn't acceptable. That pin also carries unrelated middleware changes already merged to cycloid-cli develop ahead of #471: - GetComponentConfig gained version-selector params (versionTag, versionBranch, versionCommitHash, versionID). Pass through the zero-value ("", "", "", 0) at all 3 call sites, matching how cycloid-cli's own create/update commands call it (auto-resolve current version). - models.NewEnvironment.Type changed from *string to string; drop the now-unnecessary ptr.Ptr() wrapping at both call sites. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Client support for the nav-ordering endpoint (PROD-774):
GET/PUT /organizations/{org}/nav.NavItem{Type, Key, Position}andNavConfig{Items}mirror the backend's models exactly (type:"native"|"plugin_widget",key,positionuint32 >= 1). Mirrors the existingOIDCOrganizationSettingspattern (cmd/cycloid/middleware/organization_oidc.go) — a hand-defined type in the middleware package plusGenericRequest, rather than swagger-driven codegen, since it's a simple two-field GET/PUT pair.UpdateOrgNavalways sends an explicit[]for a nil/empty items slice, never JSONnull— an empty array is what resets the ordering to defaults per the API contract; omitting the field or sendingnullis not the same thing.Dependency — please don't merge yet
The backend endpoint is currently missing from
developdue to a regression: ENGBE-282. Restore PR open at cycloidio/youdeploy-http-api#5977, not yet merged. This CLI change compiles and is self-contained (it's just a client method addition), butGetOrgNav/UpdateOrgNavwill 404 against a live backend until that PR merges.Intended consumer
A new
cycloid_organization_nav_orderresource interraform-provider-cycloid(TFPRO-55) — PR to follow this one, will point itsgo.modat this branch until this merges.🤖 Generated with a fleet worker session — https://claude.ai/code/session_014CST9mw3ABSA4aYHNy96EV