Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions packages/db/scripts/seed/postgres/seed-db.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func main() {

// Clean up existing data for idempotent re-seeding.
// Delete child rows that have ON DELETE NO ACTION constraints
// before deleting the team and user.
// before deleting the team and user rows.
err = authDb.TestsRawSQL(ctx, `
DELETE FROM envs WHERE team_id IN (SELECT id FROM teams WHERE email = $1)
`, email)
Expand All @@ -102,33 +102,37 @@ DELETE FROM volumes WHERE team_id IN (SELECT id FROM teams WHERE email = $1)
}

err = authDb.TestsRawSQL(ctx, `
DELETE FROM addons WHERE added_by IN (SELECT id FROM auth.users WHERE email = $1)
DELETE FROM addons WHERE added_by IN (SELECT id FROM public.users WHERE email = $1)
`, email)
if err != nil {
panic(err)
}

// Now safe to delete team (team_api_keys, users_teams cascade automatically)
// Now safe to delete team (team_api_keys cascade automatically).
err = authDb.TestsRawSQL(ctx, `
DELETE FROM teams WHERE email = $1
`, email)
if err != nil {
panic(err)
}

// Now safe to delete user (access_tokens cascade automatically)
// Delete the projected user row so access_tokens and users_teams cascade.
err = authDb.TestsRawSQL(ctx, `
DELETE FROM public.users WHERE email = $1
`, email)
if err != nil {
panic(err)
}

// Delete the auth user separately.
err = authDb.TestsRawSQL(ctx, `
DELETE FROM auth.users WHERE email = $1
`, email)
if err != nil {
panic(err)
}

// Create the user
// NOTE: Inserting into auth.users fires the sync_inserts_to_public_users trigger,
// which inserts into public.users, which fires the post_user_signup trigger,
// which auto-creates a default team + users_teams row. We delete that
// trigger-created team below so we can create our own with a known ID/name.
// Create the auth user and its projected public user row explicitly.
userID := uuid.New()
err = authDb.TestsRawSQL(ctx, `
INSERT INTO auth.users (id, email)
Expand All @@ -138,11 +142,10 @@ VALUES ($1, $2)
panic(err)
}

// Remove the team auto-created by the post_user_signup trigger so we can
// create our own seed team with a deterministic ID and custom name/slug.
err = authDb.TestsRawSQL(ctx, `
DELETE FROM teams WHERE email = $1
`, email)
err = authDb.Write.UpsertPublicUser(ctx, authqueries.UpsertPublicUserParams{
ID: userID,
Email: email,
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed trigger-created team cleanup causes duplicate teams

High Severity

The INSERT INTO auth.users at line 138 still fires the sync_inserts_to_public_users trigger, which inserts into public.users, which fires the post_user_signup trigger (moved to public.users by migration 20260316130000). That trigger creates a default team and users_teams row. The old code explicitly deleted this trigger-created team before creating the seed team, but that cleanup step was removed. The UpsertPublicUser call at line 145 is effectively a no-op since the row already exists from the sync trigger, and it doesn't suppress post_user_signup. The seed now produces two teams and two users_teams entries (both with is_default = true), breaking the deterministic single-team setup the seed intends to create.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit ed6c0b6. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seeding runs either manually on cluster creation or in integration tests. we can life with this until merging #2421 right after

if err != nil {
panic(err)
}
Expand Down
8 changes: 8 additions & 0 deletions packages/local-dev/seed-local-database.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ ON CONFLICT (id) DO UPDATE SET
return fmt.Errorf("failed to upsert user: %w", err)
}

err = db.Write.UpsertPublicUser(ctx, authqueries.UpsertPublicUserParams{
ID: userID,
Email: "user@e2b-dev.local",
})
if err != nil {
return fmt.Errorf("failed to upsert public user: %w", err)
}

return nil
}

Expand Down
7 changes: 7 additions & 0 deletions tests/integration/internal/utils/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@ VALUES ($1, $2)
`, userID, fmt.Sprintf("user-test-integration-%s@e2b.dev", userID))
require.NoError(t, err)

err = db.AuthDb.Write.UpsertPublicUser(t.Context(), authqueries.UpsertPublicUserParams{
ID: userID,
Email: fmt.Sprintf("user-test-integration-%s@e2b.dev", userID),
})
require.NoError(t, err)

t.Cleanup(func() {
_ = db.AuthDb.Write.DeletePublicUser(t.Context(), userID)
db.AuthDb.TestsRawSQL(t.Context(), `
DELETE FROM auth.users WHERE id = $1
`, userID)
Expand Down
8 changes: 8 additions & 0 deletions tests/integration/seed.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ VALUES ($1, $2)
return fmt.Errorf("failed to create user: %w", err)
}

err = authdb.Write.UpsertPublicUser(ctx, authqueries.UpsertPublicUserParams{
ID: data.UserID,
Email: "user-test-integration@e2b.dev",
})
if err != nil {
return fmt.Errorf("failed to create public user: %w", err)
}

// Access token
tokenWithoutPrefix := strings.TrimPrefix(data.AccessToken, keys.AccessTokenPrefix)
accessTokenBytes, err := hex.DecodeString(tokenWithoutPrefix)
Expand Down
Loading