Skip to content

Commit 9d3159e

Browse files
authored
Merge branch 'main' into group-dls-part-2
2 parents 2f0806d + 04223cc commit 9d3159e

2 files changed

Lines changed: 26 additions & 10 deletions

File tree

sdks/typescript/tests/integration.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ describe.skipIf(SKIP_TESTS)("OpenRAG TypeScript SDK Integration", () => {
251251
// due to embedding model component errors in layer 0
252252
expect(result.status).toBeDefined();
253253
expect((result as any).successful_files).toBeGreaterThanOrEqual(0);
254-
});
254+
}, 120_000);
255255

256256
it("should ingest a document without waiting", async () => {
257257
// wait=false returns immediately with task_id

src/services/user_service.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,36 @@ async def ensure_user_row(session: AsyncSession, user: User) -> UserRow:
108108
except IntegrityError:
109109
# The collision could be on any of the three unique constraints:
110110
# (oauth_provider, oauth_subject), email_lookup_hash, or id (PK).
111-
# Only the FIRST means we hit our own identity (same logical
112-
# user via concurrent insert by a peer process); the latter two
113-
# mean a *different* identity already owns that id or email.
114111
await session.rollback()
112+
113+
# Case 1: (oauth_provider, oauth_subject) race — a peer process beat us
114+
# to the INSERT for this exact identity.
115115
existing = await user_repo.get_by_oauth(provider, subject)
116116
if existing:
117117
await user_repo.update_last_login(existing.id)
118118
return existing
119-
# PK collision across providers (different subject chose the
120-
# same id). Retry with a UUID id; (provider, subject) and email
121-
# differ from the conflicting row so this insert succeeds.
122-
# email_lookup_hash collision is NOT recoverable here — that's
123-
# a real conflict (two identities with the same email) and we
124-
# let it propagate to the caller.
119+
120+
# Case 2: email_lookup_hash race — same email already inserted (most
121+
# common for the synthetic anonymous@localhost user in no-auth mode when
122+
# two concurrent requests both observe an empty table). Look up by email;
123+
# if the row's (provider, subject) matches ours it's a concurrent insert
124+
# of the same identity and we can safely return it.
125+
if user.email:
126+
by_email = await user_repo.get_by_email(user.email)
127+
if (
128+
by_email
129+
and by_email.oauth_provider == provider
130+
and by_email.oauth_subject == subject
131+
):
132+
await user_repo.update_last_login(by_email.id)
133+
return by_email
134+
135+
# Case 3: PK collision across providers (a different identity already
136+
# occupies id=subject). Retry with a UUID; (provider, subject) differs
137+
# from the conflicting row so the INSERT will succeed.
138+
# If the collision was on email_lookup_hash for a genuinely different
139+
# identity (two real users sharing an email) this insert also fails —
140+
# that propagates to the caller as intended.
125141
new_id = str(uuid.uuid4())
126142
row = UserRow(
127143
id=new_id,

0 commit comments

Comments
 (0)