Skip to content

feat: use the new api based chproxy#3648

Merged
chronark merged 16 commits intomainfrom
07-22-feat_use_the_new_api_based_chproxy
Jul 23, 2025
Merged

feat: use the new api based chproxy#3648
chronark merged 16 commits intomainfrom
07-22-feat_use_the_new_api_based_chproxy

Conversation

@chronark
Copy link
Collaborator

@chronark chronark commented Jul 22, 2025

What does this PR do?

Adds a ClickHouse proxy client to support sending analytics events through an internal proxy service instead of directly to ClickHouse. This implementation:

  1. Creates a new ClickHouseProxyClient class that handles sending batched events to internal proxy endpoints
  2. Updates the Analytics class to conditionally use the proxy client for writes when configured
  3. Maintains the original ClickHouse client for queries/reads
  4. Implements proxy methods for key verifications, API requests, and ratelimits

Fixes # (issue)

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Chore (refactoring code, technical debt, workflow improvements)
  • Enhancement (small improvements)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How should this be tested?

  • Configure the API with both clickhouseInsertUrl and clickhouseProxyToken and verify events are sent through the proxy
  • Verify that when the proxy client is not configured, the original ClickHouse client is used
  • Test sending verification, API request, and ratelimit events through the proxy

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Unkey Docs if changes were necessary

Summary by CodeRabbit

  • New Features

    • Added support for sending analytics event data through a dedicated proxy client, enabling secure and flexible event submission.
    • Introduced detailed Prometheus metrics for batch processing performance and HTTP request body sizes.
    • Enhanced error handling for analytics event inserts, providing clearer feedback on failures.
    • Increased batch sizes for analytics data processing to improve throughput.
  • Bug Fixes

    • Enhanced reliability of analytics event submission by ensuring proper fallback mechanisms when proxy configuration is unavailable.
  • Chores

    • Updated Prometheus metric naming for buffer-related metrics to improve clarity.
    • Removed deprecated generic batch processing utility to streamline codebase.

@vercel
Copy link

vercel bot commented Jul 22, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
dashboard ⬜️ Ignored (Inspect) Visit Preview Jul 23, 2025 11:42am
engineering ⬜️ Ignored (Inspect) Visit Preview Jul 23, 2025 11:42am

@changeset-bot
Copy link

changeset-bot bot commented Jul 22, 2025

⚠️ No Changeset found

Latest commit: 1ce4b65

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 22, 2025

Warning

Rate limit exceeded

@chronark has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 12 minutes and 9 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 6d15bc0 and 1ce4b65.

📒 Files selected for processing (4)
  • .github/workflows/job_test_api_local.yaml (1 hunks)
  • apps/api/src/pkg/analytics.ts (2 hunks)
  • apps/api/src/pkg/clickhouse-proxy.ts (1 hunks)
  • apps/api/src/pkg/middleware/init.ts (1 hunks)
📝 Walkthrough
## Walkthrough

A new `ClickHouseProxyClient` class was introduced to handle batched event inserts to ClickHouse via a proxy HTTP API. The `Analytics` class was updated to use this proxy client for inserts if configured, and its constructor and insert methods were adjusted accordingly. Error handling for proxy-based inserts was standardized. Additional changes include increasing batch sizes in the ClickHouse client, adding Prometheus metrics for batch processing and HTTP request body sizes, renaming some buffer metrics, and modifying batch processor flush logic to include flush trigger labels. A generic batch processing utility was removed.

## Changes

| File(s)                                      | Change Summary                                                                                              |
|----------------------------------------------|------------------------------------------------------------------------------------------------------------|
| apps/api/src/pkg/analytics.ts                 | Refactored `Analytics` to always instantiate a `ClickHouse` client for queries/reads; conditionally instantiate `ClickHouseProxyClient` for inserts if proxy config is present. Updated constructor and insert methods to use proxy client with error handling. |
| apps/api/src/pkg/clickhouse-proxy.ts          | Added new `ClickHouseProxyClient` class with methods to send batched event data to internal ClickHouse proxy API endpoints. Centralized HTTP request logic and error handling. |
| go/pkg/batch/consume.go                        | Deleted generic batch processing utility function `Process` that batched items and flushed periodically.    |
| go/pkg/batch/process.go                        | Modified `BatchProcessor` to add a flush trigger string parameter to flush function; updated flush calls and wrapped flush with Prometheus metrics instrumentation. |
| go/pkg/clickhouse/client.go                    | Increased batch size from 1000 to 10000 for three batch processors (API requests, key verifications, rate limits). |
| go/pkg/prometheus/metrics/batch.go             | Added new Prometheus metrics for batch processing: batch size distribution histogram, batch operations counter, and items processed counter. |
| go/pkg/prometheus/metrics/buffer.go            | Renamed buffer-related Prometheus metrics: changed subsystem from "api" to "buffer" and updated metric names accordingly. |
| go/pkg/prometheus/metrics/http.go              | Added new histogram metric to track HTTP request body sizes with predefined buckets.                        |
| go/pkg/zen/middleware_metrics.go               | Added a line to record HTTP request body size metric in middleware, labeled by method, path, and status.    |
| apps/api/src/pkg/env.ts                          | Removed `CLICKHOUSE_INSERT_URL` env var; added `CLICKHOUSE_PROXY_URL` and `CLICKHOUSE_PROXY_TOKEN` optional env vars. |
| apps/api/src/pkg/middleware/init.ts             | Updated `Analytics` instantiation to use `clickhouseProxyUrl` and `clickhouseProxyToken` from env vars instead of `clickhouseInsertUrl`; adjusted indentation and formatting. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Caller
    participant Analytics
    participant ClickHouse
    participant ClickHouseProxyClient

    Caller->>Analytics: new Analytics({ clickhouseUrl, clickhouseInsertUrl, clickhouseProxyToken })
    Analytics->>ClickHouse: instantiate for queries/reads
    alt Proxy config provided
        Analytics->>ClickHouseProxyClient: instantiate for inserts
    end
sequenceDiagram
    participant Caller
    participant Analytics
    participant ClickHouse
    participant ClickHouseProxyClient

    Caller->>Analytics: insertApiRequest(event)
    alt ProxyClient configured
        Analytics->>ClickHouseProxyClient: insertApiRequests([event])
        ClickHouseProxyClient-->>Analytics: Promise<void> (error captured)
        Analytics-->>Caller: { err: null | Error }
    else
        Analytics->>ClickHouse: api.insert(event)
        ClickHouse-->>Analytics: Promise<void>
        Analytics-->>Caller: result
    end
Loading

Estimated code review effort

3 (~40 minutes)

Possibly related PRs

Suggested reviewers

  • perkinsjr
  • mcstepp
  • MichaelUnkey

</details>

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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= -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details>
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=unkeyed/unkey&utm_content=3648):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

Copy link
Collaborator Author

chronark commented Jul 22, 2025

@chronark chronark marked this pull request as ready for review July 22, 2025 16:08
@vercel vercel bot temporarily deployed to Preview – dashboard July 22, 2025 16:09 Inactive
@vercel vercel bot temporarily deployed to Preview – engineering July 22, 2025 16:10 Inactive
@github-actions
Copy link
Contributor

github-actions bot commented Jul 23, 2025

Thank you for following the naming conventions for pull request titles! 🙏

Base automatically changed from 07-22-chore_replace_chproxy_with_our_own_api to main July 23, 2025 09:01
@chronark chronark requested a review from imeyer as a code owner July 23, 2025 09:01
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
apps/api/src/pkg/analytics.ts (1)

9-24: Address missing parameter passing as noted in previous review.

The constructor properly handles conditional proxy client instantiation, but as mentioned in the previous review comment, the clickhouseProxyToken parameter needs to be passed from the calling code and CI workflows need updates.

The constructor logic is correct for conditional proxy client creation when both URL and token are provided.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f4d95a and 2fcf4dd.

📒 Files selected for processing (2)
  • apps/api/src/pkg/analytics.ts (2 hunks)
  • apps/api/src/pkg/clickhouse-proxy.ts (1 hunks)
🧠 Learnings (2)
apps/api/src/pkg/analytics.ts (3)

Learnt from: chronark
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/logs-table.tsx:100-118
Timestamp: 2025-01-31T13:50:45.004Z
Learning: Sensitive data in logs is masked at the API layer (apps/api/src/pkg/middleware/metrics.ts) before being written to Clickhouse. This includes redacting API keys, plaintext values, and authorization headers using regex replacements.

Learnt from: chronark
PR: #2294
File: apps/api/src/pkg/keys/service.ts:268-271
Timestamp: 2024-10-20T07:05:55.471Z
Learning: In apps/api/src/pkg/keys/service.ts, ratelimitAsync is a table relation, not a column selection. When querying, ensure that table relations are included appropriately, not as columns.

Learnt from: chronark
PR: #2544
File: apps/api/src/pkg/env.ts:4-6
Timestamp: 2024-10-23T12:05:31.121Z
Learning: The cloudflareRatelimiter type definition in apps/api/src/pkg/env.ts should not have its interface changed; it should keep the limit method returning Promise<{ success: boolean }> without additional error properties.

apps/api/src/pkg/clickhouse-proxy.ts (1)

Learnt from: chronark
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/logs-table.tsx:100-118
Timestamp: 2025-01-31T13:50:45.004Z
Learning: Sensitive data in logs is masked at the API layer (apps/api/src/pkg/middleware/metrics.ts) before being written to Clickhouse. This includes redacting API keys, plaintext values, and authorization headers using regex replacements.

🧰 Additional context used
🧠 Learnings (2)
apps/api/src/pkg/analytics.ts (3)

Learnt from: chronark
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/logs-table.tsx:100-118
Timestamp: 2025-01-31T13:50:45.004Z
Learning: Sensitive data in logs is masked at the API layer (apps/api/src/pkg/middleware/metrics.ts) before being written to Clickhouse. This includes redacting API keys, plaintext values, and authorization headers using regex replacements.

Learnt from: chronark
PR: #2294
File: apps/api/src/pkg/keys/service.ts:268-271
Timestamp: 2024-10-20T07:05:55.471Z
Learning: In apps/api/src/pkg/keys/service.ts, ratelimitAsync is a table relation, not a column selection. When querying, ensure that table relations are included appropriately, not as columns.

Learnt from: chronark
PR: #2544
File: apps/api/src/pkg/env.ts:4-6
Timestamp: 2024-10-23T12:05:31.121Z
Learning: The cloudflareRatelimiter type definition in apps/api/src/pkg/env.ts should not have its interface changed; it should keep the limit method returning Promise<{ success: boolean }> without additional error properties.

apps/api/src/pkg/clickhouse-proxy.ts (1)

Learnt from: chronark
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/logs-table.tsx:100-118
Timestamp: 2025-01-31T13:50:45.004Z
Learning: Sensitive data in logs is masked at the API layer (apps/api/src/pkg/middleware/metrics.ts) before being written to Clickhouse. This includes redacting API keys, plaintext values, and authorization headers using regex replacements.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Build / Build
  • GitHub Check: Test Packages / Test
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (9)
apps/api/src/pkg/clickhouse-proxy.ts (5)

5-12: LGTM: Clean constructor implementation with proper URL normalization.

The constructor correctly normalizes the base URL by removing trailing slashes and stores the required parameters as private readonly fields.


17-31: LGTM: Well-structured verification events insert method.

The method signature includes all necessary fields for key verification events with proper TypeScript typing. The delegation to sendEvents provides good separation of concerns.


36-60: LGTM: Comprehensive API request events structure.

The method captures all relevant API request metrics including headers, body, latency, and geographical information. The type definitions are thorough and appropriate for analytics purposes.


65-76: LGTM: Simple and effective rate limit events method.

The rate limit event structure includes the essential fields needed for tracking rate limiting decisions with proper boolean typing for the passed field.


91-91: X-Unkey-Metrics header correctly disables internal metrics

The X-Unkey-Metrics: "disabled" header is explicitly checked in our Go middleware and rate-limit handler to skip buffering any events. Including it in clickhouse-proxy.ts aligns with the intended behavior—no further changes are needed.

• go/pkg/zen/middleware_metrics.go
– Skips BufferApiRequest when Header.Get("X-Unkey-Metrics") == "disabled"
• apps/api/routes/v2_ratelimit_limit/handler.go
– Skips BufferRatelimit under the same header check

apps/api/src/pkg/analytics.ts (4)

3-3: LGTM: Clean import and property declaration.

The import statement and optional property declaration are properly structured for the proxy client integration.

Also applies to: 7-7


40-58: LGTM: Consistent proxy integration pattern with proper error handling.

The conditional proxy usage pattern is well-implemented:

  • Returns async function when proxy is available
  • Maintains consistent error handling with { err: null | Error } return type
  • Falls back to original ClickHouse client when proxy is unavailable
  • Properly handles both Error instances and other thrown values

61-82: LGTM: Consistent implementation with verification events.

The method follows the same pattern as insertRatelimit with proper type definitions and error handling. The event structure matches the proxy client's expected interface.


85-116: LGTM: Comprehensive API request event handling.

The method maintains consistency with the other insert methods and includes all necessary fields for API request analytics. The extensive type definition ensures data integrity.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
apps/api/src/pkg/clickhouse-proxy.ts (1)

82-103: Consider implementing timeout configuration for HTTP requests.

The sendEvents method could benefit from timeout configuration to prevent long-running requests from blocking the application, as suggested in the previous review.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 799f069 and 6d15bc0.

📒 Files selected for processing (4)
  • apps/api/src/pkg/analytics.ts (2 hunks)
  • apps/api/src/pkg/clickhouse-proxy.ts (1 hunks)
  • apps/api/src/pkg/env.ts (1 hunks)
  • apps/api/src/pkg/middleware/init.ts (1 hunks)
🧠 Learnings (4)
apps/api/src/pkg/env.ts (2)

Learnt from: ogzhanolguncu
PR: #3292
File: apps/dashboard/lib/trpc/routers/key/create.ts:11-14
Timestamp: 2025-06-02T11:09:58.791Z
Learning: In the unkey codebase, TypeScript and the env() function implementation already provide sufficient validation for environment variables, so additional runtime error handling for missing env vars is not needed.

Learnt from: chronark
PR: #3161
File: go/pkg/clickhouse/schema/databases/001_verifications/002_raw_key_verifications_v1.sql:31-33
Timestamp: 2025-04-22T14:40:51.459Z
Learning: The ClickHouse table schemas in the codebase mirror the production environment and cannot be modified directly in PRs without careful migration planning.

apps/api/src/pkg/middleware/init.ts (2)

Learnt from: chronark
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/logs-table.tsx:100-118
Timestamp: 2025-01-31T13:50:45.004Z
Learning: Sensitive data in logs is masked at the API layer (apps/api/src/pkg/middleware/metrics.ts) before being written to Clickhouse. This includes redacting API keys, plaintext values, and authorization headers using regex replacements.

Learnt from: chronark
PR: #2832
File: go/cmd/api/main.go:88-88
Timestamp: 2025-01-24T08:55:18.790Z
Learning: The metrics middleware in the API v2 implementation is intentionally initialized with nil configuration during development, with the understanding that proper configuration will be added before production deployment.

apps/api/src/pkg/analytics.ts (3)

Learnt from: chronark
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/logs-table.tsx:100-118
Timestamp: 2025-01-31T13:50:45.004Z
Learning: Sensitive data in logs is masked at the API layer (apps/api/src/pkg/middleware/metrics.ts) before being written to Clickhouse. This includes redacting API keys, plaintext values, and authorization headers using regex replacements.

Learnt from: chronark
PR: #2544
File: apps/api/src/pkg/env.ts:4-6
Timestamp: 2024-10-23T12:05:31.121Z
Learning: The cloudflareRatelimiter type definition in apps/api/src/pkg/env.ts should not have its interface changed; it should keep the limit method returning Promise<{ success: boolean }> without additional error properties.

Learnt from: chronark
PR: #2294
File: apps/api/src/pkg/keys/service.ts:268-271
Timestamp: 2024-10-20T07:05:55.471Z
Learning: In apps/api/src/pkg/keys/service.ts, ratelimitAsync is a table relation, not a column selection. When querying, ensure that table relations are included appropriately, not as columns.

apps/api/src/pkg/clickhouse-proxy.ts (2)

Learnt from: chronark
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/logs-table.tsx:100-118
Timestamp: 2025-01-31T13:50:45.004Z
Learning: Sensitive data in logs is masked at the API layer (apps/api/src/pkg/middleware/metrics.ts) before being written to Clickhouse. This includes redacting API keys, plaintext values, and authorization headers using regex replacements.

Learnt from: chronark
PR: #2544
File: apps/api/src/pkg/env.ts:4-6
Timestamp: 2024-10-23T12:05:31.121Z
Learning: The cloudflareRatelimiter type definition in apps/api/src/pkg/env.ts should not have its interface changed; it should keep the limit method returning Promise<{ success: boolean }> without additional error properties.

🪛 GitHub Actions: autofix.ci
apps/api/src/pkg/analytics.ts

[error] 52-52: biome lint/style/noNonNullAssertion: Forbidden non-null assertion. Unsafe fix suggested: replace with optional chain operator ?.


[error] 79-79: biome lint/style/noNonNullAssertion: Forbidden non-null assertion. Unsafe fix suggested: replace with optional chain operator ?.


[error] 116-116: biome lint/style/noNonNullAssertion: Forbidden non-null assertion. Unsafe fix suggested: replace with optional chain operator ?.


[warning] 50-50: Suppression comment has no effect. Remove the suppression or make sure you are suppressing the correct rule.


[warning] 77-77: Suppression comment has no effect. Remove the suppression or make sure you are suppressing the correct rule.


[warning] 114-114: Suppression comment has no effect. Remove the suppression or make sure you are suppressing the correct rule.

🧰 Additional context used
🧠 Learnings (4)
apps/api/src/pkg/env.ts (2)

Learnt from: ogzhanolguncu
PR: #3292
File: apps/dashboard/lib/trpc/routers/key/create.ts:11-14
Timestamp: 2025-06-02T11:09:58.791Z
Learning: In the unkey codebase, TypeScript and the env() function implementation already provide sufficient validation for environment variables, so additional runtime error handling for missing env vars is not needed.

Learnt from: chronark
PR: #3161
File: go/pkg/clickhouse/schema/databases/001_verifications/002_raw_key_verifications_v1.sql:31-33
Timestamp: 2025-04-22T14:40:51.459Z
Learning: The ClickHouse table schemas in the codebase mirror the production environment and cannot be modified directly in PRs without careful migration planning.

apps/api/src/pkg/middleware/init.ts (2)

Learnt from: chronark
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/logs-table.tsx:100-118
Timestamp: 2025-01-31T13:50:45.004Z
Learning: Sensitive data in logs is masked at the API layer (apps/api/src/pkg/middleware/metrics.ts) before being written to Clickhouse. This includes redacting API keys, plaintext values, and authorization headers using regex replacements.

Learnt from: chronark
PR: #2832
File: go/cmd/api/main.go:88-88
Timestamp: 2025-01-24T08:55:18.790Z
Learning: The metrics middleware in the API v2 implementation is intentionally initialized with nil configuration during development, with the understanding that proper configuration will be added before production deployment.

apps/api/src/pkg/analytics.ts (3)

Learnt from: chronark
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/logs-table.tsx:100-118
Timestamp: 2025-01-31T13:50:45.004Z
Learning: Sensitive data in logs is masked at the API layer (apps/api/src/pkg/middleware/metrics.ts) before being written to Clickhouse. This includes redacting API keys, plaintext values, and authorization headers using regex replacements.

Learnt from: chronark
PR: #2544
File: apps/api/src/pkg/env.ts:4-6
Timestamp: 2024-10-23T12:05:31.121Z
Learning: The cloudflareRatelimiter type definition in apps/api/src/pkg/env.ts should not have its interface changed; it should keep the limit method returning Promise<{ success: boolean }> without additional error properties.

Learnt from: chronark
PR: #2294
File: apps/api/src/pkg/keys/service.ts:268-271
Timestamp: 2024-10-20T07:05:55.471Z
Learning: In apps/api/src/pkg/keys/service.ts, ratelimitAsync is a table relation, not a column selection. When querying, ensure that table relations are included appropriately, not as columns.

apps/api/src/pkg/clickhouse-proxy.ts (2)

Learnt from: chronark
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/logs-table.tsx:100-118
Timestamp: 2025-01-31T13:50:45.004Z
Learning: Sensitive data in logs is masked at the API layer (apps/api/src/pkg/middleware/metrics.ts) before being written to Clickhouse. This includes redacting API keys, plaintext values, and authorization headers using regex replacements.

Learnt from: chronark
PR: #2544
File: apps/api/src/pkg/env.ts:4-6
Timestamp: 2024-10-23T12:05:31.121Z
Learning: The cloudflareRatelimiter type definition in apps/api/src/pkg/env.ts should not have its interface changed; it should keep the limit method returning Promise<{ success: boolean }> without additional error properties.

🪛 GitHub Actions: autofix.ci
apps/api/src/pkg/analytics.ts

[error] 52-52: biome lint/style/noNonNullAssertion: Forbidden non-null assertion. Unsafe fix suggested: replace with optional chain operator ?.


[error] 79-79: biome lint/style/noNonNullAssertion: Forbidden non-null assertion. Unsafe fix suggested: replace with optional chain operator ?.


[error] 116-116: biome lint/style/noNonNullAssertion: Forbidden non-null assertion. Unsafe fix suggested: replace with optional chain operator ?.


[warning] 50-50: Suppression comment has no effect. Remove the suppression or make sure you are suppressing the correct rule.


[warning] 77-77: Suppression comment has no effect. Remove the suppression or make sure you are suppressing the correct rule.


[warning] 114-114: Suppression comment has no effect. Remove the suppression or make sure you are suppressing the correct rule.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Test Go API Local / Test
  • GitHub Check: Build / Build
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Test Packages / Test
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (6)
apps/api/src/pkg/env.ts (1)

35-36: LGTM! Environment schema properly configured for proxy client.

The addition of optional CLICKHOUSE_PROXY_URL and CLICKHOUSE_PROXY_TOKEN properties follows the existing schema pattern and maintains backward compatibility.

apps/api/src/pkg/middleware/init.ts (1)

99-103: LGTM! Analytics initialization correctly updated for proxy configuration.

The middleware properly passes the new proxy URL and token from environment variables to the Analytics constructor, maintaining consistency with the updated schema.

apps/api/src/pkg/analytics.ts (2)

10-26: Constructor properly handles optional proxy configuration.

The conditional instantiation of the proxy client when both URL and token are provided is correct and maintains backward compatibility.


63-84: Fix the placement of biome-ignore comments.

Similar to the previous method, move the biome-ignore comment from line 76 to line 77.

-        // biome-ignore lint/style/noNonNullAssertion: <explanation>
+        // biome-ignore lint/style/noNonNullAssertion: proxyClient existence verified above
         return await wrap(this.proxyClient!.insertVerifications([event]), err => new FetchError(
⛔ Skipped due to learnings
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Make sure to add relevant anchor comments whenever a file or piece of code is too complex, very important, confusing, or could have a bug.
apps/api/src/pkg/clickhouse-proxy.ts (2)

1-13: Well-structured proxy client implementation.

The class properly encapsulates the proxy communication logic with clear separation of concerns. The constructor correctly normalizes the base URL.


92-92: Good practice: Preventing metrics recursion.

The X-Unkey-Metrics: disabled header prevents recursive metrics collection when the proxy itself generates metrics, avoiding potential infinite loops.

chronark and others added 3 commits July 23, 2025 13:31
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@graphite-app
Copy link

graphite-app bot commented Jul 23, 2025

Graphite Automations

"Notify author when CI fails" took an action on this PR • (07/23/25)

1 teammate was notified to this PR based on Andreas Thomas's automation.

"Post a GIF when PR approved" took an action on this PR • (07/23/25)

1 gif was posted to this PR based on Andreas Thomas's automation.

Flo4604
Flo4604 approved these changes Jul 23, 2025
Copy link
Member

Flo4604 commented Jul 23, 2025

nvm someone else has to approvie this

@graphite-app
Copy link

graphite-app bot commented Jul 23, 2025

Photo gif. A hand giving a thumbs-up appears in front of a photo of Harrison Ford. (Added via Giphy)

@chronark chronark merged commit 07a91df into main Jul 23, 2025
19 checks passed
@chronark chronark deleted the 07-22-feat_use_the_new_api_based_chproxy branch July 23, 2025 13:30
@coderabbitai coderabbitai bot mentioned this pull request Sep 12, 2025
18 tasks
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