Skip to content

chore(deps): pnpm 12, and ClickHouse row validation on - #86

Merged
fylorn merged 1 commit into
devfrom
chore/pnpm12-ch-validation
Oct 6, 2026
Merged

fylorn merged 1 commit into
devfrom
chore/pnpm12-ch-validation

Conversation

@fylorn

@fylorn fylorn commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #85. It does two things: moves the frontend to pnpm 12, and turns the ClickHouse client's row validation on once every read had been checked.

pnpm 12.9.1

  • Changes packageManager, the pnpm/action-setup version in CI, and the Corepack pin in Dockerfile.web.
  • The lockfile: pnpm 12 adds a second YAML document of 158 lines, with nothing removed. That document pins pnpm@12.9.1 and lists 14 per-platform @pnpm/exe.* binaries. lockfileVersion stays 9.0. A local pnpm 11 switches itself to 12.9.1 and leaves the lockfile alone.
  • CI: pnpm/action-setup v6.1.0, already pinned, supports pnpm 12. It installs a pinned 12.x and then runs pnpm self-update to the requested version. pnpm store path, which setup-node's cache step runs, returns the same path as before.
  • Docker: Corepack 0.36 on node:24.21.0-alpine prepares 12.9.1 and runs the native musl binary.
  • Supply chain: published through GitHub Actions trusted publishing, with SLSA v1 provenance. The integrity hashes of the platform binaries in the lockfile match the registry.
  • Checks run with pnpm 12: install --frozen-lockfile, check:i18n, lint, test (143 tests) and build all pass; the web image builds and serves the app.

ClickHouse row validation, on

With validation, the clickhouse crate checks each result against the Rust row it lands in. A type that drifts then fails the query instead of decoding into garbage. #85 left validation off until every read had been checked. Checking them found three bugs:

  • Route-history sparkline: toUnixTimestamp returns UInt32 into i64, and the quantiles of the Nullable latency_ms are Nullable(Float64) into f64. Under plain RowBinary that misread the stream; the handler swallows the error and returns an empty history.
  • Trace timestamps: formatDateTime(..., '%M') gives the month name in ClickHouse, not the minute (for example 04:August:52). This affected trace events and both log-body endpoints; they now use %i.
  • Trace never showed app logs: the created_at String alias shadowed the column in PREWHERE created_at >= now() - …. The String-to-DateTime comparison failed, and unwrap_or_default turned that into "no app events". The column is now qualified as app_logs.created_at.

How the reads were checked

  1. Every read site, statically. I ran DESCRIBE on all 68 ClickHouse reads, including every variant of the dynamic SQL (ranges, group_by dimensions, scoped and unscoped), on 26.8 LTS and on 26.9, and compared names and types with the Rust structs using the crate's validation rules. The five insert structs were compared against their tables the same way. After the fixes there are no mismatches.
  2. New tests/clickhouse_row_types.rs.
    • It seeds all five log tables, and through their materialised views the rollups, with rows that have no NULLs. Validation only checks the first row and non-NULL values, so empty or NULL results prove nothing.
    • It then calls every endpoint that reads ClickHouse in each of its shapes: global and team-scoped, 24h/7d/30d, compare, and every group_by.
    • Endpoints that hide a failed query behind an empty answer are asserted to return data. Trace timestamps must be RFC 3339.
    • ClickHouse's query_log confirms that every query variant ran and returned rows. The one exception is the all-empty group_by, which the handler cannot produce.
  3. The test harness now builds the per-test client with the production create_client: the same settings, the same validation and the same connector.

Checks run locally

  • cargo fmt --check, clippy --all-targets -D warnings, and 755 unit tests.
  • The full integration suite (411 tests) on ClickHouse 26.8 and on 26.9.

🤖 Generated with Claude Code

pnpm 12.9.1 in package.json, CI and Dockerfile.web; the lockfile gains
the pnpm 12 binary document (14 per-platform entries), lockfileVersion
unchanged.

The ClickHouse client keeps the crate's row validation on. Every read
was checked: DESCRIBE of all 68 query sites and their variants against
the Rust rows on 26.8 and 26.9, and a new integration test that seeds
complete rows and calls each reading endpoint in each shape. That found
and fixes three bugs: route history decoded UInt32 and Nullable
quantiles into i64/f64 and came back empty; formatDateTime's %M is the
month name, so trace and log-body timestamps read "04:August:52"; and
the trace's app-log query compared the String alias created_at with a
DateTime, failed, and showed no app events. The test harness now builds
its client with the production create_client.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@fylorn
fylorn merged commit 2e23fd9 into dev Oct 6, 2026
6 checks passed
@fylorn
fylorn deleted the chore/pnpm12-ch-validation branch October 6, 2026 04:57
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