fix(seed): serialize SAML seed; drop overlay cast

Two cleanups in seed-dummy-data, both flagged on PR #1395:

- The parallel `Promise.all` block ran `seedSamlConnections(projectId)`
  alongside another `overrideEnvironmentConfigOverride` write on the same
  project (`payments.testMode`). Both are read-modify-write, so concurrent
  reads of the env config can each see the stale state and the second
  write clobbers the first — the existing TODO at `config.ts:491` already
  documents the underlying race. Sequence the SAML seed after the
  parallel block to avoid the race until the override is wrapped in a
  serializable txn.

- Type the SAML overlay with the target parameter type directly instead
  of using an `as Parameters<...>` cast, per project style.
This commit is contained in:
Bilal Godil 2026-04-29 18:42:59 -07:00
parent aaeb8318a8
commit 1e912c7548

View File

@ -1983,7 +1983,7 @@ async function seedSamlConnections(projectId: string): Promise<void> {
// dot-keys — config normalization with onDotIntoNonObject="ignore"
// drops dot-keys that try to navigate into a record entry that
// doesn't yet exist (same convention as auth.oauth.providers).
const overlay: Record<string, unknown> = {};
const overlay: Parameters<typeof overrideEnvironmentConfigOverride>[0]["environmentConfigOverrideOverride"] = {};
for (const f of fetched) {
overlay[`auth.saml.connections.${f.slug}`] = {
displayName: f.displayName,
@ -1998,7 +1998,7 @@ async function seedSamlConnections(projectId: string): Promise<void> {
await overrideEnvironmentConfigOverride({
projectId,
branchId: DEFAULT_BRANCH_ID,
environmentConfigOverrideOverride: overlay as Parameters<typeof overrideEnvironmentConfigOverride>[0]["environmentConfigOverrideOverride"],
environmentConfigOverrideOverride: overlay,
});
}
@ -2131,7 +2131,6 @@ export async function seedDummyProject(options: SeedDummyProjectOptions): Promis
"payments.testMode": true,
},
}),
...(getEnvVariable("STACK_SEED_ENABLE_SAML", "false") === "true" ? [seedSamlConnections(projectId)] : []),
...options.skipGithubConfigSource ? [] : [setBranchConfigOverrideSource({
projectId,
branchId: DEFAULT_BRANCH_ID,
@ -2154,6 +2153,16 @@ export async function seedDummyProject(options: SeedDummyProjectOptions): Promis
}),
]);
// Run sequentially after the parallel block. Both this and the
// `payments.testMode` write above target the same environment config,
// and `overrideEnvironmentConfigOverride` is read-modify-write — running
// them in parallel races and one write clobbers the other (TODO at
// config.ts:491 already documents this). Sequencing avoids the race
// until the underlying override is wrapped in a serializable txn.
if (getEnvVariable("STACK_SEED_ENABLE_SAML", "false") === "true") {
await seedSamlConnections(projectId);
}
await seedDummyTransactions({
prisma: dummyPrisma,
tenancyId: dummyTenancy.id,