import { hashBucket } from "~/utils/computeBucket"; /** Subset of the global flags snapshot this resolver reads. */ export type ComputeMigrationFlags = { computeMigrationEnabled?: boolean; computeMigrationFreePercentage?: number; computeMigrationPaidPercentage?: number; }; type MigrationDecisionInput = { planType: string | undefined; orgId: string; orgFeatureFlags: Record | null | undefined; flags: ComputeMigrationFlags | undefined; }; /** * Whether this org should run on the compute backing. Shared by the trigger-time * transform and the deploy-time template decision so a migrated org always gets a * compute template. Precedence: per-org override (both directions) wins; otherwise * global enable + the plan's percentage bucket. Enterprise and unknown plans are * never enrolled by percentage (override only). The sole opt-out is the per-org * `computeMigrationEnabled: false`. */ export function isOrgMigrated({ planType, orgId, orgFeatureFlags, flags, }: MigrationDecisionInput): boolean { const override = orgFeatureFlags?.["computeMigrationEnabled"]; if (override === false) return false; if (override === true) return true; if (!(flags?.computeMigrationEnabled ?? false)) return false; const pct = planType === "free" ? (flags?.computeMigrationFreePercentage ?? 0) : planType === "paid" ? (flags?.computeMigrationPaidPercentage ?? 0) : 0; // enterprise / undefined return hashBucket(orgId) < pct; } type ResolveInput = MigrationDecisionInput & { baseWorkerQueue: string | undefined; baseEnableFastPath: boolean; region: string | undefined; // geo of the base queue (same whether migrated or not) backing: { workerQueue: string; enableFastPath: boolean } | undefined; envType: string; }; /** * Produce the target descriptor `{ workerQueue, region, enableFastPath }` for a * run. When the org is migrated and the region has a compute backing, the queue * and fast-path setting come from the MICROVM backing group; `region` is the geo * either way. Same-geo swap (us-east-1 -> us-east-1-next): any explicit placement * is a geography preference, honored by staying in-region. Applied after region * resolution, mirroring the scheduled-split. */ export function resolveComputeMigration({ baseWorkerQueue, baseEnableFastPath, region, backing, envType, ...decision }: ResolveInput): { workerQueue: string | undefined; region: string | undefined; enableFastPath: boolean; } { const passthrough = { workerQueue: baseWorkerQueue, region, enableFastPath: baseEnableFastPath }; if (baseWorkerQueue === undefined) return passthrough; if (envType === "DEVELOPMENT") return passthrough; if (!isOrgMigrated(decision)) return passthrough; if (!backing) return passthrough; return { workerQueue: backing.workerQueue, region, enableFastPath: backing.enableFastPath }; }