Skip to content

Commit 4b7f66d

Browse files
committed
refactor(webapp): drop FK on env default region; reuse canonical resolver
- RuntimeEnvironment.defaultWorkerGroupId is now a plain nullable column (no FK, no relation, no index): a deleted region is tolerated and resolution falls back to project -> global. Avoids Prisma drift and FK-check overhead on a cold table. - api.v1.workers and computeTemplateCreation.resolveMode now reuse getDefaultWorkerGroupForProject instead of re-reading the global flag, so their isDefault / MICROVM decisions match exactly where runs route (and resolve the global default the same way as the trigger path).
1 parent 43bcd08 commit 4b7f66d

6 files changed

Lines changed: 15 additions & 46 deletions

File tree

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

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,10 @@ import {
44
WorkersCreateResponseBody,
55
WorkersListResponseBody,
66
} from "@trigger.dev/core/v3";
7-
import { $replica } from "~/db.server";
87
import {
98
createActionApiRoute,
109
createLoaderApiRoute,
1110
} from "~/services/routeBuilders/apiBuilder.server";
12-
import { FEATURE_FLAG } from "~/v3/featureFlags";
13-
import { makeFlag } from "~/v3/featureFlags.server";
14-
import { resolveEffectiveDefaultWorkerGroupId } from "~/v3/regionAccess.server";
1511
import { WorkerGroupService } from "~/v3/services/worker/workerGroupService.server";
1612

1713
export const loader = createLoaderApiRoute(
@@ -31,23 +27,19 @@ export const loader = createLoaderApiRoute(
3127
projectId: authentication.environment.projectId,
3228
});
3329

34-
const globalDefaultWorkerGroupId = await makeFlag($replica)({
35-
key: FEATURE_FLAG.defaultWorkerInstanceGroupId,
36-
});
37-
38-
// env default -> project default -> global default
39-
const effectiveDefaultWorkerGroupId = resolveEffectiveDefaultWorkerGroupId({
30+
// Reuse the trigger path's resolution so isDefault matches where runs
31+
// actually route: env default -> project default -> global default.
32+
const defaultWorkerGroup = await service.getDefaultWorkerGroupForProject({
33+
projectId: authentication.environment.projectId,
4034
environmentDefaultWorkerGroupId: authentication.environment.defaultWorkerGroupId,
41-
projectDefaultWorkerGroupId: authentication.environment.project.defaultWorkerGroupId,
42-
globalDefaultWorkerGroupId,
4335
});
4436

4537
return json(
4638
workers.map((w) => ({
4739
type: w.type,
4840
name: w.name,
4941
description: w.description,
50-
isDefault: w.id === effectiveDefaultWorkerGroupId,
42+
isDefault: w.id === defaultWorkerGroup?.id,
5143
updatedAt: w.updatedAt,
5244
}))
5345
);

apps/webapp/app/services/upsertBranch.server.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,7 @@ export class UpsertBranchService {
120120
shortcode,
121121
maximumConcurrencyLimit: parentEnvironment.maximumConcurrencyLimit,
122122
// Inherit the region from the parent preview environment.
123-
defaultWorkerGroup: parentEnvironment.defaultWorkerGroupId
124-
? { connect: { id: parentEnvironment.defaultWorkerGroupId } }
125-
: undefined,
123+
defaultWorkerGroupId: parentEnvironment.defaultWorkerGroupId,
126124
organization: {
127125
connect: {
128126
id: parentEnvironment.organization.id,

apps/webapp/app/v3/services/computeTemplateCreation.server.ts

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ import type { PrismaClientOrTransaction } from "~/db.server";
88
import type { AuthenticatedEnvironment } from "~/services/apiAuth.server";
99
import { ServiceValidationError } from "./baseService.server";
1010
import { FailDeploymentService } from "./failDeployment.server";
11-
import { resolveComputeAccess, resolveEffectiveDefaultWorkerGroupId } from "../regionAccess.server";
12-
import { FEATURE_FLAG } from "../featureFlags";
13-
import { makeFlag } from "../featureFlags.server";
11+
import { resolveComputeAccess } from "../regionAccess.server";
12+
import { WorkerGroupService } from "./worker/workerGroupService.server";
1413

1514
type TemplateCreationMode = "required" | "shadow" | "skip";
1615

@@ -146,7 +145,6 @@ export class ComputeTemplateCreationService {
146145
const project = await prisma.project.findFirst({
147146
where: { id: authenticatedEnv.projectId },
148147
select: {
149-
defaultWorkerGroupId: true,
150148
organization: {
151149
select: { featureFlags: true },
152150
},
@@ -157,23 +155,13 @@ export class ComputeTemplateCreationService {
157155
return "skip";
158156
}
159157

160-
// Resolve the region this env actually deploys to: env default -> project default -> global default.
161-
const globalDefaultWorkerGroupId = await makeFlag(prisma)({
162-
key: FEATURE_FLAG.defaultWorkerInstanceGroupId,
163-
});
164-
const effectiveDefaultWorkerGroupId = resolveEffectiveDefaultWorkerGroupId({
158+
// Reuse the trigger path's resolution so the template decision matches the
159+
// region runs actually deploy to: env default -> project default -> global default.
160+
const defaultWorkerGroup = await new WorkerGroupService().getDefaultWorkerGroupForProject({
161+
projectId: authenticatedEnv.projectId,
165162
environmentDefaultWorkerGroupId: authenticatedEnv.defaultWorkerGroupId,
166-
projectDefaultWorkerGroupId: project.defaultWorkerGroupId,
167-
globalDefaultWorkerGroupId,
168163
});
169164

170-
const defaultWorkerGroup = effectiveDefaultWorkerGroupId
171-
? await prisma.workerInstanceGroup.findFirst({
172-
where: { id: effectiveDefaultWorkerGroupId },
173-
select: { workloadType: true },
174-
})
175-
: null;
176-
177165
if (defaultWorkerGroup?.workloadType === "MICROVM") {
178166
return "required";
179167
}
Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,2 @@
11
-- AlterTable
22
ALTER TABLE "public"."RuntimeEnvironment" ADD COLUMN IF NOT EXISTS "defaultWorkerGroupId" TEXT;
3-
4-
-- AddForeignKey
5-
ALTER TABLE "public"."RuntimeEnvironment" DROP CONSTRAINT IF EXISTS "RuntimeEnvironment_defaultWorkerGroupId_fkey";
6-
ALTER TABLE "public"."RuntimeEnvironment" ADD CONSTRAINT "RuntimeEnvironment_defaultWorkerGroupId_fkey" FOREIGN KEY ("defaultWorkerGroupId") REFERENCES "public"."WorkerInstanceGroup"("id") ON DELETE SET NULL ON UPDATE CASCADE;

internal-packages/database/prisma/migrations/20260609142055_add_environment_default_worker_group_index/migration.sql

Lines changed: 0 additions & 3 deletions
This file was deleted.

internal-packages/database/prisma/schema.prisma

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,8 @@ model RuntimeEnvironment {
354354
orgMember OrgMember? @relation(fields: [orgMemberId], references: [id], onDelete: SetNull, onUpdate: Cascade)
355355
orgMemberId String?
356356
357-
/// The default region for this environment. Falls back to the project default, then the global default.
358-
defaultWorkerGroup WorkerInstanceGroup? @relation("EnvironmentDefaultWorkerGroup", fields: [defaultWorkerGroupId], references: [id])
357+
/// The default region (WorkerInstanceGroup) for this environment. Deliberately not a foreign key:
358+
/// a deleted region is tolerated — resolution falls back to the project default, then the global default.
359359
defaultWorkerGroupId String?
360360
361361
createdAt DateTime @default(now())
@@ -401,7 +401,6 @@ model RuntimeEnvironment {
401401
@@index([parentEnvironmentId])
402402
@@index([projectId])
403403
@@index([organizationId])
404-
@@index([defaultWorkerGroupId])
405404
}
406405

407406
/// Records of previously-valid API keys that are still accepted for authentication
@@ -1522,8 +1521,7 @@ model WorkerInstanceGroup {
15221521
workers WorkerInstance[]
15231522
backgroundWorkers BackgroundWorker[]
15241523
1525-
defaultForProjects Project[] @relation("ProjectDefaultWorkerGroup")
1526-
defaultForEnvironments RuntimeEnvironment[] @relation("EnvironmentDefaultWorkerGroup")
1524+
defaultForProjects Project[] @relation("ProjectDefaultWorkerGroup")
15271525
15281526
organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)
15291527
organizationId String?

0 commit comments

Comments
 (0)