Problem
In src/middleware/idempotency.ts lines 15-38, checkIdempotency performs a read-then-write without atomicity:
const existing = await db.query.idempotencyKeys.findFirst({ ... });
if (existing) { ... return cached response; }
// Gap: another request can insert the same key here
await db.insert(idempotencyKeys).values({ ... });
Two concurrent requests with the same idempotency key can both pass the findFirst check and both attempt to insert. The second insert fails with a primary key unique constraint violation, which propagates as an unhandled 500 error.
Fix
Use INSERT ... ON CONFLICT DO NOTHING or a database-level unique constraint with conflict handling.
Severity
Medium — race condition under concurrent load
Problem
In
src/middleware/idempotency.tslines 15-38,checkIdempotencyperforms a read-then-write without atomicity:Two concurrent requests with the same idempotency key can both pass the
findFirstcheck and both attempt toinsert. The second insert fails with a primary key unique constraint violation, which propagates as an unhandled 500 error.Fix
Use
INSERT ... ON CONFLICT DO NOTHINGor a database-level unique constraint with conflict handling.Severity
Medium — race condition under concurrent load