Skip to content

fix(api): remediate ClickStack OpenAPI drift (#1112) - #1121

Closed
sdairs wants to merge 4 commits into
cursor/openapi-drift-1112-api-clickpipes-c05dfrom
cursor/openapi-drift-1112-api-clickstack-c05d
Closed

sdairs wants to merge 4 commits into
cursor/openapi-drift-1112-api-clickpipes-c05dfrom
cursor/openapi-drift-1112-api-clickstack-c05d

Conversation

@sdairs

@sdairs sdairs commented Oct 21, 2026

Copy link
Copy Markdown
Member

Part 3 of 3 of the API side of the #1112 drift remediation. Fixes #1112. Stacked on API 2 (#1119, cursor/openapi-drift-1112-api-clickpipes-c05d). The plan, the decisions I was unsure about, and the follow-up issues are in the API 1 description (#1117, cursor/openapi-drift-remediation-1112-c05d).

At this head, python3 scripts/check-openapi-drift.py --dry-run against the live spec reports 0 actionable drift.

Library

  • New operation. The beta click_stack_validate_webhook checks a ClickStackWebhookInput without saving it and returns ClickStackValidateWebhookResponse (valid, errors, normalized). It's added to BETA_OPERATIONS; its metadata was regenerated in API 1.
  • Role permissions. ClickStackCASLPermission/ClickStackCASLPermissionResponse are unions on integration: ClickStackMongoDBCASLPermission (conditions are a map of raw JSON values) and ClickStackClickHouseCASLPermission (typed connection/table/where conditions). action and subject are now enums, and the free-form conditions alias is gone.
  • Dashboard filters. ClickStackFilter, ClickStackFilterResponse and ClickStackFilterInput are unions on type (query expression, static list, Prometheus label, source). Each variant gains min_selections, max_selections (integer enums) and is_global_requirement.
  • Heatmaps. ClickStackHeatmapChartConfig{,Response} are unions on heatmapMode. A missing heatmapMode selects the distribution heatmap (the former shape); a missing mode with groupBy is kept verbatim.
  • Alerts. ClickStackAlertChartConfig is a union of the line, stacked-bar, stacked-line and number configs plus the overlay fields. Create/update requests now require only threshold, interval and thresholdType, so channel, channels and source become Option. Alerts gain displayName, tags and chartConfig, and the source enums add Inline.
  • Tiles. Stacked-line tiles (ClickStackStackedLineChartConfig) join the tile union; lineInterpolation, raw-SQL number colorRules, tile description, the source expressions and saved-filter all are added; stacked_line joins the time-chart series enum.
  • Select-item level. level is Option<f64>, matching the numeric schema.
  • Write-back. TryFrom covers the permission and filter unions and their variants, and the source and saved-filter conversions carry the new fields. Chart and tile configs follow the existing precedent of having no write-back conversions.
  • ClickStackSourceResponse gets #[allow(clippy::large_enum_variant)]: the four new trace-source fields crossed the size threshold, and boxing would break callers that match on the variant.
  • The README covers the Rust caller migration.

The ClickStackValidationError* types are no longer in the spec, but nothing reports them and removing them would be an unforced break, so I left them.

Analyzer

A typed additionalProperties map whose value schema is an inline oneOf/anyOf now matches only serde_json::Value. Without this rule, no Rust type could satisfy ClickStackMongoDBCASLPermissionConditions (string or {"$regex", "$options"} values). Fixture tests cover both the accepted and the rejected representations. The report format is unchanged.

CLI (compile fixes only)

  • Filters and role permissions are now unions, which serde_ignored can't see into. So that unknown fields are still rejected, the CLI checks each filter and permission against its variant on the raw JSON. Permissions must now set integration to mongodb or clickhouse, as the spec requires; integration-less fixtures were updated.
  • Everything the CLI didn't accept before stays rejected until CLI 3: inline alerts, missing source, non-query-expression filters, and series heatmaps. Channel/channels are still both required. A test pins each case.
  • Select-item level is now sent as a number. The dashboard fixture pins "level": 0.95.

Tests

Union dispatch (including dropped discriminators and unknown values), request strictness, missing/null tolerance for each new response type, write-back with missing-field names at the nested level, wiremock coverage for the new method (success and API error), facade paths, and analyzer fixtures. The library has no live ClickStack suite, so there's no integration step to extend.

Verification

  • cargo fmt --all; library clippy; both clickhousectl clippy configurations; cargo check -p clickhousectl --no-default-features; cargo check --workspace --all-features: all clean.
  • cargo test -p clickhouse-cloud-api -p clickhouse-openapi-analyzer --no-fail-fast: all pass, including spec_coverage_test.
  • cargo test -p clickhousectl and python3 -m unittest discover -s scripts/tests -p 'test_*.py': pass.
  • Live dry run: Actionable drift: 0 ... No actionable drift. Library fully covers the live spec.
  • No files added or renamed.
Open in Web Open in Cursor 

cursoragent and others added 4 commits October 21, 2026 17:01
#1112)

A typed map whose value schema is an inline oneOf/anyOf has no single Rust
value type; serde_json::Value is the only lossless match. Every other value
schema still needs a typed value.

Co-authored-by: Alasdair Brown <sdairs@users.noreply.github.com>
- Add click_stack_validate_webhook with its operation metadata and beta entry.
- Role permissions, dashboard filters and heatmaps become unions matching the
  spec's oneOf schemas, with TryFrom write-back for permissions and filters.
- Add stacked-line tiles and inline alert chart configs; alerts gain
  displayName, tags and chartConfig, and channel/channels/source are optional.
- Add the remaining ClickStack fields and enum values, and type select-item
  level as a number.

Co-authored-by: Alasdair Brown <sdairs@users.noreply.github.com>
#1112)

Compile fixes for the library's new unions. Filters and role permissions are
checked per variant on the raw JSON so unknown fields are still rejected;
inline alerts, non-query-expression filters and series heatmaps stay rejected
until the CLI exposes them. Select-item level is now sent as a number.

Co-authored-by: Alasdair Brown <sdairs@users.noreply.github.com>
Co-authored-by: Alasdair Brown <sdairs@users.noreply.github.com>
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

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.

3 participants