Skip to content

Model acknowledged OpenAPI enum constraints as typed Rust values #296

Description

@sdairs

Context

Follow-up to #297, which implemented #295 on top of #290.

The shared OpenAPI drift analyzer inventories enum constraints that are not backed by concrete Rust value types. This issue tracks the 11 scalar-backed locations acknowledged when the analyzer landed.

Reviewed against main and the live OpenAPI spec on 2026-08-13:

  • All original 11 locations remain scalar-backed and acknowledged.
  • Their OpenAPI constraints and values have not changed since this issue was filed.
  • The live analyzer reports 13 acknowledged unsupported constraints: these 11 plus two later UDF attachment error-response constraints. The UDF constraints have a separate inline justification and are outside this issue.
  • A report with zero actionable drift does not mean these locations are resolved; the acknowledgements suppress them pending this work or a reviewed decision to retain a scalar type.

Current locations

Deprecated API-key roles

  • ApiKey.roles
  • ApiKeyPostRequest.roles
  • ApiKeyPatchRequest.roles

These fields are deprecated in favor of assignedRoles / assignedRoleIds and are hidden unless the deprecated-fields feature is enabled. Review whether changing their exported types is worthwhile. Retaining scalar types is acceptable if the compatibility decision is documented beside their acknowledgement entries.

Query API endpoint roles

  • ServiceQueryAPIEndpoint.roles
  • InstanceServiceQueryApiEndpointsPostRequest.roles

These remain Vec<String>. The CLI also exposes query endpoint roles through repeatable --role strings and currently passes them through without validating the two spec values. Request and response representations should follow the current direction-aware model policy; response values must remain tolerant of unknown future values.

BYOC availability-zone suffixes

  • ByocInfrastructurePostRequest.availabilityZoneSuffixes

This remains Vec<String> although the spec constrains values to a through f.

Upgrade-window numeric values

  • UpgradeWindow.startHourUtc
  • UpgradeWindow.duration
  • UpgradeWindowPutRequest.startHourUtc

These remain integers. Use typed numeric representations or constrained newtypes with Serde behavior matching the OpenAPI wire values. Keep request and response types distinct where required by the current model policy, and update the UpgradeWindow to UpgradeWindowPutRequest conversion.

Slow-query list parameters

  • slow_query_patterns_get_list.sort_by
  • slow_query_patterns_get_list.sort_order

These remain Option<&str> parameters on the public API client.

Changes since filing

  • API models and client methods now live in private per-domain modules behind the existing public facade.
  • Request and response models are direction-aware: requests are strict while every response field is optional and tolerant of absence.
  • The analyzer now verifies opt-in enum VALUES constants. If query-endpoint roles are validated by the CLI, source accepted values from the library type rather than adding another hand-maintained list.
  • The API-key role fields are feature-gated as deprecated fields.

Implementation notes

  • Review public clickhouse-cloud-api compatibility before changing exported fields or client signatures.
  • Give response enums an unknown-value catch-all so a newly added API value does not break deserialization.
  • Use Serde wire values exactly matching the OpenAPI document.
  • Update model exports, client signatures, response-to-request conversions, CLI callers, and tests together.
  • Remove an acknowledgement when its location becomes analyzer-checkable. If a scalar type is deliberately retained, keep the acknowledgement with a nearby comment explaining why.
  • Keep the two inline UDF attachment error-response acknowledgements outside this issue; they have no public client/model type today.

Acceptance criteria

  • Each of the 11 locations is represented by a typed Rust value or has an explicit, reviewed justification for remaining scalar-backed.
  • Remediated locations are checked bidirectionally by the shared analyzer.
  • Acknowledgement entries are removed for remediated locations; intentionally retained entries have a nearby justification.
  • Query endpoint --role values are sourced from the library type and validated if the request field becomes typed.
  • Request, response, conversion, client, CLI, and compatibility tests cover the chosen representations.
  • cargo test --workspace passes.
  • cargo clippy --workspace --all-targets -- -D warnings passes.
  • cargo fmt --all --check passes.
  • cargo check --workspace --all-features passes if deprecated API-key fields change.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requesttest-coverageLive API integration test coverage work

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions