Fix OpenAPI drift: 36 gaps between live spec and library (#298)#299
Conversation
Remediate all 36 actionable drift findings from issue #298. API library changes: - Add click_pipe_schema_discovery client method (POST /clickpipes/schemaDiscovery) - Add 4 new model types: ClickPipeSchemaDiscoveryField, Request, Response, Source - Add shared AutoscalingMode enum (vertical/horizontal) used by 7 structs - Add autoscalingMode field to Service, ServicePostRequest, ServiceReplicaScalingPatchRequest, ServiceScalingPatchResponse, ScalingScheduleBaseConfig, ScalingScheduleEntry, ScalingScheduleEntryRequest - Add serverId field to ClickPipeMySQLSource, ClickPipeMutateMySQLSource, ClickPipePatchMySQLSource - Remove extra fields: replicaMemoryGb from ServicePostRequest, ServiceReplicaScalingPatchRequest, ScalingScheduleEntryRequest; numReplicas + replicaMemoryGb from ScalingScheduleEntry - Add ca-central-1 to 8 region enums - Add stopped to PgStateProperty enum - Regenerate BETA_OPERATIONS (adds click_pipe_schema_discovery) - Replace vendored OpenAPI snapshot with live spec Analyzer config changes: - Add optionality exemption for ServicePostRequest.autoscalingMode - Remove stale optionality exemption for ServicePostRequest.replicaMemoryGb CLI compile fixes (no new surface): - Add autoscaling_mode/server_id to struct constructions in commands.rs - Remove replica_memory_gb from struct constructions in commands.rs Tests: - Add focused tests for new models, AutoscalingMode, ca-central-1, stopped, server_id, and click_pipe_schema_discovery wiremock - Update existing tests for removed/renamed fields
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 8b144b8. Configure here.
…291) Replace eight hand-maintained KNOWN_* constant lists in the CLI with pub const VALUES on the library enums they validate against. The analyzer now verifies that any enum declaring a VALUES const has it exactly equal (as a set) to its non-catch-all wire values, producing FindingKind::EnumValuesMismatch on mismatch. Library (models.rs): - Add pub const VALUES to 9 enums: PgHaType, PgProvider, PgVersion, ServicePatchRequestReleasechannel, ServicePostRequestCompliancetype, ServicePostRequestProfile, ServicePostRequestProvider, ServicePostRequestRegion, ServicePostRequestReleasechannel. - VALUES on ServicePostRequestRegion includes europe-west2 and ca-central-1, fixing existing drift where the CLI rejected valid regions. Analyzer (clickhouse-openapi-analyzer): - rust_inventory.rs: parse Item::Impl blocks in models.rs to extract VALUES const string literals into EnumInfo.values_const. - report.rs: add FindingKind::EnumValuesMismatch, bump REPORT_SCHEMA_VERSION from 1 to 2. - compare.rs: compare_enum_values_consts checks every enum with a VALUES const against its wire values (set equality); emits EnumValuesMismatch with details[missing] and details[extra]. Python issue rendering: - check-openapi-drift.py: schema version check -> 2, summary table row and simple_sections entry for enum_values_mismatch. - test_check_openapi_drift.py: synthetic finding, assertion, and schema version rejection test updated. CLI (clickhousectl): - commands.rs: delete KNOWN_PROVIDERS, KNOWN_REGIONS, KNOWN_RELEASE_CHANNELS, KNOWN_COMPLIANCE_TYPES, KNOWN_PROFILES; use Enum::VALUES in parse_serde_enum calls. - postgres.rs: delete KNOWN_PG_PROVIDERS, KNOWN_PG_VERSIONS, KNOWN_PG_HA_TYPES; use Enum::VALUES in parse_serde_enum and PossibleValuesParser calls. Closes #291.
An impl block that lexically precedes its enum declaration was silently skipped, disabling the VALUES drift guard for that enum. Trait impls with an associated VALUES const were also misattributed. Address both review findings and replace the vacuous non-enum-impl test assertion. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ift-guard Derive CLI value lists from library enums with analyzer drift guard
| let Some(values_const) = &info.values_const else { | ||
| continue; | ||
| }; | ||
| let rust_values = &info.values; |
There was a problem hiding this comment.
🟡 Medium src/compare.rs:447
compare_enum_values_consts reports every enum value as missing when VALUES is initialized from a non-literal source. Because string_array returns an empty BTreeSet for initializers like pub const VALUES: &[&str] = SHARED_VALUES, lines 451–452 treat that empty parse result as the constant's real value, so rust_values.difference(values_const) flags every variant as missing and the analyzer fails with false drift even though the constant is correct at runtime. Consider skipping the comparison when values_const is empty (or distinguishing a genuinely empty constant from an unparseable one).
| let Some(values_const) = &info.values_const else { | |
| continue; | |
| }; | |
| let rust_values = &info.values; | |
| let Some(values_const) = &info.values_const else { | |
| continue; | |
| }; | |
| if values_const.is_empty() { | |
| continue; | |
| } | |
| let rust_values = &info.values; |
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @crates/clickhouse-openapi-analyzer/src/compare.rs around lines 447-450:
`compare_enum_values_consts` reports every enum value as missing when `VALUES` is initialized from a non-literal source. Because `string_array` returns an empty `BTreeSet` for initializers like `pub const VALUES: &[&str] = SHARED_VALUES`, lines 451–452 treat that empty parse result as the constant's real value, so `rust_values.difference(values_const)` flags every variant as missing and the analyzer fails with false drift even though the constant is correct at runtime. Consider skipping the comparison when `values_const` is empty (or distinguishing a genuinely empty constant from an unparseable one).

Summary
Remediates all 36 actionable OpenAPI drift findings from #298. Library-only change; no new CLI surface.
API library (
clickhouse-cloud-api)click_pipe_schema_discovery(POST/v1/organizations/{orgId}/services/{serviceId}/clickpipes/schemaDiscovery, Beta)ClickPipeSchemaDiscoveryField,ClickPipeSchemaDiscoveryRequest,ClickPipeSchemaDiscoveryResponse,ClickPipeSchemaDiscoverySourceAutoscalingMode(Vertical/Horizontal) used by 7 structsautoscalingModeonService,ServicePostRequest,ServiceReplicaScalingPatchRequest,ServiceScalingPatchResponse,ScalingScheduleBaseConfig,ScalingScheduleEntry,ScalingScheduleEntryRequestserverIdonClickPipeMySQLSource,ClickPipeMutateMySQLSource,ClickPipePatchMySQLSourcereplicaMemoryGbfrom 4 structs,numReplicas+replicaMemoryGbfromScalingScheduleEntryca-central-1added to 8 region enums;stoppedadded toPgStatePropertyBETA_OPERATIONS(42→43, addsclick_pipe_schema_discovery)Analyzer (
clickhouse-openapi-analyzer)("ServicePostRequest", "autoscalingMode")— server defaults to vertical when omitted("ServicePostRequest", "replicaMemoryGb")— field no longer existsCLI (
clickhousectl)Compile fixes only (no new commands/flags):
autoscaling_mode/server_idto struct constructions incommands.rsreplica_memory_gbfrom struct constructions incommands.rsTests
AutoscalingModeround-trip + catch-all,PgStateProperty::Stopped,ServiceRegion/ByocConfigRegionidca-central-1, schema discovery response/request/field serde, MySQLserver_idclick_pipe_schema_discovery_kafkaCloses #298.
Verification
cargo test -p clickhouse-cloud-api -p clickhouse-openapi-analyzer— all passcargo clippy --workspace --all-targets --all-features -- -D warnings— cleanpython3 -m unittest discover -s scripts/tests -p 'test_*.py'— 3/3 passpython3 scripts/check-openapi-drift.py --dry-run— Actionable drift: 0