Skip to content

Commit d03b1fa

Browse files
matt-aitkenclaude
andcommitted
Fix CI: stale clickhouseInstance imports + Devin events-default routing
CI failures on the previous push had two causes: 1. Three files (AgentListPresenter, sessions list route, api.v1.sessions) still imported clickhouseClient from ~/services/clickhouseInstance.server, a path that was deleted by the initial commit of this branch. They came in via the recent merge from main and broke typecheck + e2e on production webapp boot. All three now resolve their ClickHouse client per-call via clickhouseFactory (async, awaits factory.isReady()), matching the pattern used elsewhere in the PR for non-hot-path callers. 2. getClickhouseForOrganizationSync's default branch grouped 'standard' and 'events' together to return defaultClickhouseClient — but 'events' should resolve to defaultEventsClickhouseClient (EVENTS_CLICKHOUSE_URL singleton). The bug was unreachable today because the only caller of the events default path resolves via getEventsClickhouseClient() directly, but the API contract is now correct for any future caller. Flagged by Devin Review. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d9506f7 commit d03b1fa

4 files changed

Lines changed: 35 additions & 20 deletions

File tree

apps/webapp/app/presenters/v3/AgentListPresenter.server.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import {
33
type RuntimeEnvironmentType,
44
type TaskTriggerSource,
55
} from "@trigger.dev/database";
6-
import { ClickHouse } from "@internal/clickhouse";
6+
import { type ClickHouse } from "@internal/clickhouse";
77
import { z } from "zod";
88
import { $replica } from "~/db.server";
9-
import { clickhouseClient } from "~/services/clickhouseInstance.server";
9+
import { clickhouseFactory } from "~/services/clickhouse/clickhouseFactoryInstance.server";
1010
import { singleton } from "~/utils/singleton";
1111
import { findCurrentWorkerFromEnvironment } from "~/v3/models/workerDeployment.server";
1212

@@ -24,10 +24,7 @@ export type AgentActiveState = {
2424
};
2525

2626
export class AgentListPresenter {
27-
constructor(
28-
private readonly clickhouse: ClickHouse,
29-
private readonly _replica: PrismaClientOrTransaction
30-
) {}
27+
constructor(private readonly _replica: PrismaClientOrTransaction) {}
3128

3229
public async call({
3330
organizationId,
@@ -40,6 +37,11 @@ export class AgentListPresenter {
4037
environmentId: string;
4138
environmentType: RuntimeEnvironmentType;
4239
}) {
40+
const clickhouse = await clickhouseFactory.getClickhouseForOrganization(
41+
organizationId,
42+
"standard"
43+
);
44+
4345
const currentWorker = await findCurrentWorkerFromEnvironment(
4446
{
4547
id: environmentId,
@@ -89,20 +91,21 @@ export class AgentListPresenter {
8991
}
9092

9193
// All queries are deferred for streaming
92-
const activeStates = this.#getActiveStates(environmentId, slugs);
93-
const conversationSparklines = this.#getConversationSparklines(environmentId, slugs);
94-
const costSparklines = this.#getCostSparklines(environmentId, slugs);
95-
const tokenSparklines = this.#getTokenSparklines(environmentId, slugs);
94+
const activeStates = this.#getActiveStates(clickhouse, environmentId, slugs);
95+
const conversationSparklines = this.#getConversationSparklines(clickhouse, environmentId, slugs);
96+
const costSparklines = this.#getCostSparklines(clickhouse, environmentId, slugs);
97+
const tokenSparklines = this.#getTokenSparklines(clickhouse, environmentId, slugs);
9698

9799
return { agents, activeStates, conversationSparklines, costSparklines, tokenSparklines };
98100
}
99101

100102
/** Count runs currently executing vs suspended per agent */
101103
async #getActiveStates(
104+
clickhouse: ClickHouse,
102105
environmentId: string,
103106
slugs: string[]
104107
): Promise<Record<string, AgentActiveState>> {
105-
const queryFn = this.clickhouse.reader.query({
108+
const queryFn = clickhouse.reader.query({
106109
name: "agentActiveStates",
107110
query: `SELECT
108111
task_identifier,
@@ -140,10 +143,11 @@ export class AgentListPresenter {
140143

141144
/** 24h hourly sparkline of conversation (run) count per agent */
142145
async #getConversationSparklines(
146+
clickhouse: ClickHouse,
143147
environmentId: string,
144148
slugs: string[]
145149
): Promise<Record<string, number[]>> {
146-
const queryFn = this.clickhouse.reader.query({
150+
const queryFn = clickhouse.reader.query({
147151
name: "agentConversationSparklines",
148152
query: `SELECT
149153
task_identifier,
@@ -172,10 +176,11 @@ export class AgentListPresenter {
172176

173177
/** 24h hourly sparkline of LLM cost per agent */
174178
async #getCostSparklines(
179+
clickhouse: ClickHouse,
175180
environmentId: string,
176181
slugs: string[]
177182
): Promise<Record<string, number[]>> {
178-
const queryFn = this.clickhouse.reader.query({
183+
const queryFn = clickhouse.reader.query({
179184
name: "agentCostSparklines",
180185
query: `SELECT
181186
task_identifier,
@@ -203,10 +208,11 @@ export class AgentListPresenter {
203208

204209
/** 24h hourly sparkline of total tokens per agent */
205210
async #getTokenSparklines(
211+
clickhouse: ClickHouse,
206212
environmentId: string,
207213
slugs: string[]
208214
): Promise<Record<string, number[]>> {
209-
const queryFn = this.clickhouse.reader.query({
215+
const queryFn = clickhouse.reader.query({
210216
name: "agentTokenSparklines",
211217
query: `SELECT
212218
task_identifier,
@@ -284,5 +290,5 @@ export class AgentListPresenter {
284290
export const agentListPresenter = singleton("agentListPresenter", setupAgentListPresenter);
285291

286292
function setupAgentListPresenter() {
287-
return new AgentListPresenter(clickhouseClient, $replica);
293+
return new AgentListPresenter($replica);
288294
}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.sessions._index/route.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { findProjectBySlug } from "~/models/project.server";
1616
import { findEnvironmentBySlug } from "~/models/runtimeEnvironment.server";
1717
import { getSessionFiltersFromRequest } from "~/presenters/SessionFilters.server";
1818
import { SessionListPresenter } from "~/presenters/v3/SessionListPresenter.server";
19-
import { clickhouseClient } from "~/services/clickhouseInstance.server";
19+
import { clickhouseFactory } from "~/services/clickhouse/clickhouseFactoryInstance.server";
2020
import { requireUserId } from "~/services/session.server";
2121
import { docsPath, EnvironmentParamSchema } from "~/utils/pathBuilder";
2222
import { throwNotFound } from "~/utils/httpErrors";
@@ -45,7 +45,11 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
4545

4646
const filters = getSessionFiltersFromRequest(request);
4747

48-
const presenter = new SessionListPresenter($replica, clickhouseClient);
48+
const clickhouse = await clickhouseFactory.getClickhouseForOrganization(
49+
project.organizationId,
50+
"standard"
51+
);
52+
const presenter = new SessionListPresenter($replica, clickhouse);
4953
const list = await presenter.call(project.organizationId, environment.id, {
5054
userId,
5155
projectId: project.id,

apps/webapp/app/routes/api.v1.sessions.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import { SessionId } from "@trigger.dev/core/v3/isomorphic";
1111
import type { Prisma, Session } from "@trigger.dev/database";
1212
import { $replica, prisma, type PrismaClient } from "~/db.server";
13-
import { clickhouseClient } from "~/services/clickhouseInstance.server";
13+
import { clickhouseFactory } from "~/services/clickhouse/clickhouseFactoryInstance.server";
1414
import { logger } from "~/services/logger.server";
1515
import { mintSessionToken } from "~/services/realtime/mintSessionToken.server";
1616
import {
@@ -58,8 +58,12 @@ export const loader = createLoaderApiRoute(
5858
findResource: async () => 1,
5959
},
6060
async ({ searchParams, authentication }) => {
61+
const clickhouse = await clickhouseFactory.getClickhouseForOrganization(
62+
authentication.environment.organizationId,
63+
"standard"
64+
);
6165
const repository = new SessionsRepository({
62-
clickhouse: clickhouseClient,
66+
clickhouse,
6367
prisma: $replica as PrismaClient,
6468
});
6569

apps/webapp/app/services/clickhouse/clickhouseFactory.server.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,9 @@ export class ClickhouseFactory {
338338
if (!dataStore) {
339339
switch (clientType) {
340340
case "standard":
341-
case "events":
342341
return defaultClickhouseClient;
342+
case "events":
343+
return defaultEventsClickhouseClient;
343344
case "replication":
344345
return defaultRunsReplicationClickhouseClient;
345346
case "sessions_replication":

0 commit comments

Comments
 (0)