Skip to content

Pr 3333 fix#3336

Closed
deepshekhardas wants to merge 17 commits intotriggerdotdev:mainfrom
deepshekhardas:pr-3333-fix
Closed

Pr 3333 fix#3336
deepshekhardas wants to merge 17 commits intotriggerdotdev:mainfrom
deepshekhardas:pr-3333-fix

Conversation

@deepshekhardas
Copy link
Copy Markdown

Closes #

✅ Checklist

  • I have followed every step in the contributing guide
  • The PR title follows the convention.
  • I ran and tested the code works

Testing

[Describe the steps you took to test this change]


Changelog

[Short description of what has changed]


Screenshots

[Screenshots]

💯

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 7, 2026

🦋 Changeset detected

Latest commit: ffc9e6e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 29 packages
Name Type
@trigger.dev/core Patch
@trigger.dev/database Patch
@trigger.dev/build Patch
trigger.dev Patch
@trigger.dev/python Patch
@trigger.dev/redis-worker Patch
@trigger.dev/schema-to-json Patch
@trigger.dev/sdk Patch
@internal/cache Patch
@internal/clickhouse Patch
@internal/llm-model-catalog Patch
@internal/redis Patch
@internal/replication Patch
@internal/run-engine Patch
@internal/schedule-engine Patch
@internal/testcontainers Patch
@internal/tracing Patch
@internal/tsql Patch
@internal/zod-worker Patch
d3-chat Patch
references-d3-openai-agents Patch
references-nextjs-realtime Patch
references-realtime-hooks-test Patch
references-realtime-streams Patch
references-telemetry Patch
@internal/sdk-compat-tests Patch
@trigger.dev/react-hooks Patch
@trigger.dev/rsc Patch
@trigger.dev/otlp-importer Patch

Not sure what this means? Click here to learn what changesets are.

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Hi @deepshekhardas, thanks for your interest in contributing!

This project requires that pull request authors are vouched, and you are not in the list of vouched users.

This PR will be closed automatically. See https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md for more details.

@github-actions github-actions bot closed this Apr 7, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 7, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9e0cfe26-d878-45fe-bb03-db643f94bbee

📥 Commits

Reviewing files that changed from the base of the PR and between def21b2 and ffc9e6e.

📒 Files selected for processing (70)
  • .changeset/org-scoped-clickhouse.md
  • .cursor/mcp.json
  • .server-changes/organization-scoped-clickhouse.md
  • CLAUDE.md
  • apps/webapp/app/env.server.ts
  • apps/webapp/app/presenters/v3/ApiRunListPresenter.server.ts
  • apps/webapp/app/presenters/v3/CreateBulkActionPresenter.server.ts
  • apps/webapp/app/presenters/v3/RunPresenter.server.ts
  • apps/webapp/app/presenters/v3/RunTagListPresenter.server.ts
  • apps/webapp/app/presenters/v3/SpanPresenter.server.ts
  • apps/webapp/app/presenters/v3/TaskListPresenter.server.ts
  • apps/webapp/app/presenters/v3/UsagePresenter.server.ts
  • apps/webapp/app/presenters/v3/ViewSchedulePresenter.server.ts
  • apps/webapp/app/presenters/v3/WaitpointPresenter.server.ts
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.$dashboardKey/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.errors.$fingerprint/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.errors._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.logs/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models.$modelId/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models.compare/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts.$promptSlug/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.test.tasks.$taskParam/route.tsx
  • apps/webapp/app/routes/admin.api.v1.runs-replication.create.ts
  • apps/webapp/app/routes/admin.api.v1.runs-replication.start.ts
  • apps/webapp/app/routes/admin.data-stores.tsx
  • apps/webapp/app/routes/admin.tsx
  • apps/webapp/app/routes/api.v1.prompts.$slug.ts
  • apps/webapp/app/routes/api.v1.prompts.$slug.versions.ts
  • apps/webapp/app/routes/api.v1.prompts._index.ts
  • apps/webapp/app/routes/otel.v1.logs.ts
  • apps/webapp/app/routes/otel.v1.metrics.ts
  • apps/webapp/app/routes/otel.v1.traces.ts
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.logs.$logId.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.logs.ts
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts.$promptSlug.generations.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
  • apps/webapp/app/runEngine/services/triggerFailedTask.server.ts
  • apps/webapp/app/services/admin/missingLlmModels.server.ts
  • apps/webapp/app/services/clickhouse/clickhouseFactory.server.ts
  • apps/webapp/app/services/clickhouse/clickhouseSecretSchemas.server.ts
  • apps/webapp/app/services/clickhouseInstance.server.ts
  • apps/webapp/app/services/dataStores/organizationDataStoreConfigSchemas.server.ts
  • apps/webapp/app/services/dataStores/organizationDataStoresRegistry.server.ts
  • apps/webapp/app/services/dataStores/organizationDataStoresRegistryInstance.server.ts
  • apps/webapp/app/services/queryService.server.ts
  • apps/webapp/app/services/runsReplicationInstance.server.ts
  • apps/webapp/app/services/runsReplicationService.server.ts
  • apps/webapp/app/v3/eventRepository/clickhouseEventRepository.server.ts
  • apps/webapp/app/v3/eventRepository/clickhouseEventRepositoryInstance.server.ts
  • apps/webapp/app/v3/eventRepository/eventRepository.server.ts
  • apps/webapp/app/v3/eventRepository/eventRepository.types.ts
  • apps/webapp/app/v3/eventRepository/index.server.ts
  • apps/webapp/app/v3/otlpExporter.server.ts
  • apps/webapp/app/v3/services/alerts/errorAlertEvaluator.server.ts
  • apps/webapp/app/v3/services/bulk/BulkActionV2.server.ts
  • apps/webapp/test/clickhouseFactory.test.ts
  • apps/webapp/test/organizationDataStoresRegistry.test.ts
  • apps/webapp/test/runsBackfiller.test.ts
  • apps/webapp/test/runsReplicationBenchmark.test.ts
  • apps/webapp/test/runsReplicationService.part1.test.ts
  • apps/webapp/test/runsReplicationService.part2.test.ts
  • apps/webapp/test/utils/replicationUtils.ts
  • apps/webapp/test/utils/testReplicationClickhouseFactory.ts
  • apps/webapp/test/utils/tracing.ts
  • internal-packages/database/prisma/migrations/20260331212308_add_organization_data_stores/migration.sql
  • internal-packages/database/prisma/schema.prisma

Walkthrough

This pull request implements organization-scoped ClickHouse database instance routing. It introduces a new OrganizationDataStore model to store per-organization ClickHouse connection overrides, creates a ClickhouseFactory class that resolves ClickHouse clients per organization with per-hostname caching, establishes an OrganizationDataStoresRegistry to manage configurations and secrets with background reload, and systematically replaces ~50 instances of singleton ClickHouse client imports (clickhouseClient, logsClickhouseClient, queryClickhouseClient, etc.) across routes, presenters, services, and repositories with factory-based resolution. Additionally, it updates the OTLP exporter and replication services for multi-organization ClickHouse routing, adds an admin UI for data store management, and includes comprehensive test coverage for the new factory and registry systems.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 3 potential issues.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment on lines +65 to +69
const taskEventStore = parentStore ?? (await resolveTaskEventRepositoryFlag(featureFlags));
const { repository: resolvedRepository } = await clickhouseFactory.getEventRepositoryForOrganization(
taskEventStore,
organizationId
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔴 Factory throws on "postgres" store, crashing all PostgreSQL event storage paths

getEventRepository(), getConfiguredEventRepository(), and getV3EventRepository() now unconditionally call clickhouseFactory.getEventRepositoryForOrganization(taskEventStore, organizationId) before checking whether the store is "postgres". When taskEventStore resolves to "postgres" (via resolveTaskEventRepositoryFlag or the TaskRun.taskEventStore column, which defaults to "postgres"), the factory calls buildEventRepository("postgres", ...) at clickhouseFactory.server.ts:385, which throws Unknown ClickHouse event repository store: postgres. The old code never called the factory for the postgres path — it returned the postgres eventRepository directly. This will crash any org or run configured to use PostgreSQL event storage.

Affected call sites
  • index.server.ts:66getEventRepository calls factory before checking store
  • index.server.ts:44getConfiguredEventRepository calls factory before checking store
  • index.server.ts:87getV3EventRepository passes parentStore (which can be "postgres") directly to factory
Prompt for agents
The bug is that getEventRepository (and similarly getConfiguredEventRepository and getV3EventRepository) calls clickhouseFactory.getEventRepositoryForOrganization unconditionally, even when the store is 'postgres'. The factory's buildEventRepository function throws for unknown stores including 'postgres'.

The fix: in each of these functions, check if the resolved store is 'postgres' BEFORE calling the factory, and return the postgres eventRepository directly. Only call the factory for 'clickhouse' or 'clickhouse_v2' stores.

Affected functions in apps/webapp/app/v3/eventRepository/index.server.ts:
1. getEventRepository (line 60) — move the factory call inside the clickhouse branches
2. getConfiguredEventRepository (line 19) — move the factory call inside the clickhouse branches
3. getV3EventRepository (line 82) — guard the parentStore === 'postgres' case before calling factory

Alternatively, buildEventRepository in clickhouseFactory.server.ts could handle 'postgres' by returning a dummy or by not throwing, but the cleanest fix is to not call the factory at all for postgres paths.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +248 to +253
const clickhouseClient = await clickhouseFactory.getClickhouseForOrganization(
environment.organizationId,
"query"
);

const presenter = new ErrorGroupPresenter($replica, clickhouseClient, clickhouseClient);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔴 ErrorGroupPresenter receives query ClickHouse client instead of logs-specific client

The ErrorGroupPresenter constructor takes (replica, logsClickhouse, clickhouse) — two distinct ClickHouse clients. The logsClickhouse parameter was previously the dedicated logs client (from LOGS_CLICKHOUSE_URL) with specific clickhouseSettings like max_memory_usage, max_bytes_before_external_sort, and max_threads configured in the old initializeLogsClickhouseClient(). The new code at errors.$fingerprint/route.tsx:253 passes the same query client for both parameters: new ErrorGroupPresenter($replica, clickhouseClient, clickhouseClient). This means error occurrence queries (this.logsClickhouse.errors.*) will use the query client's settings instead of the logs-specific memory/sort limits, potentially causing query failures or different performance characteristics under load.

Suggested change
const clickhouseClient = await clickhouseFactory.getClickhouseForOrganization(
environment.organizationId,
"query"
);
const presenter = new ErrorGroupPresenter($replica, clickhouseClient, clickhouseClient);
const clickhouseClient = await clickhouseFactory.getClickhouseForOrganization(
environment.organizationId,
"query"
);
const logsClickhouseClient = await clickhouseFactory.getClickhouseForOrganization(
environment.organizationId,
"logs"
);
const presenter = new ErrorGroupPresenter($replica, logsClickhouseClient, clickhouseClient);
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +126 to +130
const queryClickhouse = await clickhouseFactory.getClickhouseForOrganization(
project.organizationId,
"query"
);
const presenter = new ErrorsListPresenter($replica, queryClickhouse);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚩 ErrorsListPresenter uses query client instead of logs client — matches old pattern

In the errors index route (errors._index/route.tsx:126-130), the ErrorsListPresenter is constructed with a query type ClickHouse client. The ErrorsListPresenter constructor takes (replica, clickhouse) — a single ClickHouse parameter. Looking at the old code, it used logsClickhouseClient for this. So this is also a change from logs → query client, but since ErrorsListPresenter only has one ClickHouse parameter (unlike ErrorGroupPresenter which has two), this is a deliberate consolidation. The query client may have different settings than the logs client. This is worth verifying but is a design decision rather than a clear bug.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

2 participants