ClickHouse Product Analytics
Project

Verification

Build, unit, and end-to-end verification.

The repo has two verification layers: package-level checks and a Docker-backed end-to-end test.

Package Verification

Run:

npm run verify

This runs:

  • TypeScript project references with tsc -b
  • unit tests with Vitest
  • package builds for SDK, React, and ingest service

Current unit coverage includes:

  • browser SDK queueing, identity, pageleave, alias, fetch compression, and transport behavior,
  • React provider, hook, and viewport tracking behavior,
  • ingest service validation, auth, CORS, compressed bodies, identity side effects, and request limits.

Reference Docs

Run:

npm run docs:reference

This regenerates content/docs/reference/sdk-generated from TypeScript source comments with TypeDoc. Run it after changing exported SDK or React APIs.

Run the docs app checks separately from the product package build:

npm run docs:typecheck
npm run docs:build
npm run docs:validate

End-to-End Verification

Start the source-build local stack first:

docker compose -f docker-compose-build.yml up -d --build

Then run:

npm run verify:e2e

Clean up the local stack when finished:

docker compose -f docker-compose-build.yml down -v --remove-orphans

The E2E verifier builds the Next.js smoke app, exercises the documented browser SDK, React, direct API, identity, CORS, gzip, pageview/pageleave, autocapture, and docs deployment wiring flows, then queries ClickHouse for matching events, persons, person_distinct_ids, and sessions rows. Browser and React runtime flows are executed in a DOM harness; the Next.js smoke app is built to verify framework packaging. Use docker-compose-build.yml here so ingest service changes in the current checkout are tested instead of the prebuilt GHCR image from the default compose stack.

The E2E test asserts:

  • ingest and ClickHouse health checks,
  • Fumadocs app files, content/docs, OpenAPI spec, generated reference docs, and Pages workflow wiring,
  • Next.js smoke app build,
  • browser SDK custom capture,
  • capturePageview: "history_change",
  • capturePageview: true,
  • capturePageview: false,
  • capturePageleave: true,
  • capturePageleave: "if_capture_pageview",
  • opt-out and opt-in behavior,
  • beforeSend mutation and dropping,
  • property denylist behavior,
  • autocapture for button clicks,
  • React AnalyticsProvider,
  • React useAnalytics,
  • React AnalyticsCaptureOnViewed,
  • React trackAllChildren,
  • direct one-event batch API,
  • direct multi-event batch API,
  • SDK fetch compression and direct gzip bodies,
  • $identify, $set, and $set_once,
  • separate-request anonymous-to-known identity stitching,
  • alias mapping through person_distinct_ids,
  • gzip request bodies,
  • allowed and disallowed origins,
  • invalid API key rejection,
  • max event count rejection,
  • existence of ClickHouse tables and views,
  • starter query shapes.

Successful output looks like:

{
  "status": "ok",
  "runId": "e2e_...",
  "events": 20,
  "persons": 3,
  "sessions": 2
}

Docs Verification

GitHub Pages builds the docs through .github/workflows/pages.yml with npm run docs:build. Production and preview builds use distinct build-time NEXT_PUBLIC_DOCS_BASE_PATH values because Next.js inlines basePath during static export. The workflow deploys the production docs for main and publishes same-repository PR previews under /pr-preview/pr-<number>/ when both the PR and its latest push changed docs-related files. Locally, the repo verifies the presence and wiring of docs files during E2E. The actual rendered Pages build is validated by GitHub Actions.

Deployment Artifact Checks

The CI workflow at .github/workflows/ci.yml runs package verification, Docker Compose validation, Helm chart lint/render checks, and the Docker-backed E2E suite. The container workflow at .github/workflows/container.yml builds and publishes the ingest image to GitHub Container Registry only after CI succeeds on main, producing linux/amd64 and linux/arm64 images under the same GHCR tags. The publish job then inspects the pushed manifest digest and fails if either platform is missing.

Validate deployment artifacts locally with:

docker compose config
docker compose -f docker-compose-build.yml config
helm lint ./deploy/helm/clickhouse-product-analytics \
  --set ingest.publicApiKeys=local_dev_key \
  --set clickhouse.url=http://clickhouse:8123 \
  --set clickhouse.user=analytics \
  --set clickhouse.password=local_dev_password
helm template cpa ./deploy/helm/clickhouse-product-analytics \
  --set ingest.publicApiKeys=local_dev_key \
  --set clickhouse.url=http://clickhouse:8123 \
  --set clickhouse.user=analytics \
  --set clickhouse.password=local_dev_password

Run the local ingest benchmark with:

npm run benchmark:ingest

Package publishability is checked with:

npm run release:dry-run

When To Add E2E Coverage

Add E2E assertions when documentation introduces a new public workflow, API shape, query pattern, or deployment guarantee. Unit tests are enough for internal helpers, but anything shown in /docs should either be exercised by npm run verify:e2e or explicitly documented as a static/CI-only check.

On this page