Skip to content

Commit 314a1d7

Browse files
committed
perf(webapp): skip the global feature-flag query when a per-org override resolves
flag() queried the FeatureFlag row before looking at the caller-supplied overrides, so a per-org hit still paid a round-trip. Check the override first and only fall through to the query when it fails the schema, which keeps today's resolution order intact.
1 parent c3f0d62 commit 314a1d7

2 files changed

Lines changed: 107 additions & 8 deletions

File tree

apps/webapp/app/v3/featureFlags.server.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,26 @@ export function makeFlag(_prisma: PrismaClientOrTransaction = prisma) {
2525
async function flag<T extends FeatureFlagKey>(
2626
opts: FlagsOptions<T>
2727
): Promise<z.infer<(typeof FeatureFlagCatalog)[T]> | undefined> {
28-
const value = await _prisma.featureFlag.findFirst({
29-
where: {
30-
key: opts.key,
31-
},
32-
});
33-
3428
const flagSchema = FeatureFlagCatalog[opts.key];
3529

36-
if (opts.overrides?.[opts.key] !== undefined) {
37-
const parsed = flagSchema.safeParse(opts.overrides[opts.key]);
30+
const override = opts.overrides?.[opts.key];
31+
32+
if (override !== undefined) {
33+
const parsed = flagSchema.safeParse(override);
3834

3935
if (parsed.success) {
4036
return parsed.data;
4137
}
38+
39+
// an override that fails the schema is ignored: the global value still wins
4240
}
4341

42+
const value = await _prisma.featureFlag.findFirst({
43+
where: {
44+
key: opts.key,
45+
},
46+
});
47+
4448
if (value !== null) {
4549
const parsed = flagSchema.safeParse(value.value);
4650

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// flag() resolves a per-org override without paying for the global row: a valid override
2+
// short-circuits the query, an invalid one still falls through to the global value.
3+
// NEVER mocks the DB: real testcontainers Postgres FeatureFlag rows, with the findFirst
4+
// call counted by a delegating wrapper around the real client.
5+
import type { PrismaClient } from "@trigger.dev/database";
6+
import { postgresTest } from "@internal/testcontainers";
7+
import { describe, expect, vi } from "vitest";
8+
import type { PrismaClientOrTransaction } from "~/db.server";
9+
import { FEATURE_FLAG } from "~/v3/featureFlags";
10+
import { makeFlag, makeSetFlag } from "~/v3/featureFlags.server";
11+
12+
vi.setConfig({ testTimeout: 60_000 });
13+
14+
const KEY = FEATURE_FLAG.dashboardAgentTurnEvalsEnabled;
15+
16+
function countingClient(prisma: PrismaClient) {
17+
const calls = { findFirst: 0 };
18+
const client = {
19+
featureFlag: {
20+
findFirst: (args: unknown) => {
21+
calls.findFirst++;
22+
return (prisma.featureFlag.findFirst as (a: unknown) => unknown)(args);
23+
},
24+
},
25+
} as unknown as PrismaClientOrTransaction;
26+
27+
return { client, calls };
28+
}
29+
30+
describe("flag() override resolution", () => {
31+
postgresTest(
32+
"a valid `false` override wins without querying the global row",
33+
async ({ prisma }) => {
34+
await makeSetFlag(prisma)({ key: KEY, value: true });
35+
const { client, calls } = countingClient(prisma);
36+
37+
const result = await makeFlag(client)({
38+
key: KEY,
39+
defaultValue: true,
40+
overrides: { [KEY]: false },
41+
});
42+
43+
expect(result).toBe(false);
44+
expect(calls.findFirst).toBe(0);
45+
}
46+
);
47+
48+
postgresTest(
49+
"a valid `true` override wins without querying the global row",
50+
async ({ prisma }) => {
51+
await makeSetFlag(prisma)({ key: KEY, value: false });
52+
const { client, calls } = countingClient(prisma);
53+
54+
const result = await makeFlag(client)({
55+
key: KEY,
56+
defaultValue: false,
57+
overrides: { [KEY]: true },
58+
});
59+
60+
expect(result).toBe(true);
61+
expect(calls.findFirst).toBe(0);
62+
}
63+
);
64+
65+
postgresTest(
66+
"an override that fails the schema falls through to the global value",
67+
async ({ prisma }) => {
68+
await makeSetFlag(prisma)({ key: KEY, value: true });
69+
const { client, calls } = countingClient(prisma);
70+
71+
const result = await makeFlag(client)({
72+
key: KEY,
73+
defaultValue: false,
74+
overrides: { [KEY]: "yes please" },
75+
});
76+
77+
expect(result).toBe(true);
78+
expect(calls.findFirst).toBe(1);
79+
}
80+
);
81+
82+
postgresTest("no override still queries the global row", async ({ prisma }) => {
83+
await makeSetFlag(prisma)({ key: KEY, value: true });
84+
const { client, calls } = countingClient(prisma);
85+
86+
const result = await makeFlag(client)({
87+
key: KEY,
88+
defaultValue: false,
89+
overrides: {},
90+
});
91+
92+
expect(result).toBe(true);
93+
expect(calls.findFirst).toBe(1);
94+
});
95+
});

0 commit comments

Comments
 (0)