Skip to content

feat(middleware): add per-org sidebar nav ordering (GetOrgNav/UpdateOrgNav)#471

Merged
fhacloid merged 1 commit into
developfrom
fhacloid-tfpro-55-cli-nav-order
Jul 2, 2026
Merged

feat(middleware): add per-org sidebar nav ordering (GetOrgNav/UpdateOrgNav)#471
fhacloid merged 1 commit into
developfrom
fhacloid-tfpro-55-cli-nav-order

Conversation

@fhacloid

@fhacloid fhacloid commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

What

Client support for the nav-ordering endpoint (PROD-774): GET/PUT /organizations/{org}/nav.

NavItem{Type, Key, Position} and NavConfig{Items} mirror the backend's models exactly (type: "native" | "plugin_widget", key, position uint32 >= 1). Mirrors the existing OIDCOrganizationSettings pattern (cmd/cycloid/middleware/organization_oidc.go) — a hand-defined type in the middleware package plus GenericRequest, rather than swagger-driven codegen, since it's a simple two-field GET/PUT pair.

UpdateOrgNav always sends an explicit [] for a nil/empty items slice, 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.

Dependency — please don't merge yet

The backend endpoint is currently missing from develop due 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), but GetOrgNav/UpdateOrgNav will 404 against a live backend until that PR merges.

Intended consumer

A new cycloid_organization_nav_order resource in terraform-provider-cycloid (TFPRO-55) — PR to follow this one, will point its go.mod at this branch until this merges.

🤖 Generated with a fleet worker session — https://claude.ai/code/session_014CST9mw3ABSA4aYHNy96EV

…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 fhacloid merged commit 2645bbb into develop Jul 2, 2026
4 checks passed
@fhacloid fhacloid deleted the fhacloid-tfpro-55-cli-nav-order branch July 2, 2026 10:04
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>
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