SIGN IN SIGN UP

fix(api): make thread creation atomic (#486)

* fix(api): make thread creation atomic

`if_exists` is a SELECT followed by an unconditional INSERT. Two concurrent
creates for the same `thread_id` both miss the SELECT, both INSERT, and the
loser's asyncpg `UniqueViolationError` escapes as an unhandled 500 instead of
honouring `if_exists`:

    UniqueViolationError: duplicate key value violates unique constraint
    "thread_pkey"

`if_exists="do_nothing"` is exactly the knob a caller reaches for to make
creation replay-safe, so a 500 there defeats its purpose.

Insert first and let the primary key arbitrate:
`ON CONFLICT (thread_id) DO NOTHING ... RETURNING`, then read the incumbent and
apply `if_exists` to it. The read stays scoped to the caller as before, so an ID
held by another owner is still never adopted — it now answers 409 rather than
500. No new status code, no migration, no new index, and no extra round trip
(the old happy path already issued a second statement via `session.refresh()`).

Verified against a real Postgres: at 25-30 concurrent identical creates the old
code returned 500s in 3 of 5 rounds, the new code none across 150 requests, with
exactly one row persisted each round. The new e2e test fails on the old code.

* test(api): assert concurrent creates return the stored thread

Review feedback on #486. Identical payloads meant the test only checked
`thread_id`, which every response carries by construction — a losing request that
returned a row assembled from its own input would have passed.

Each request now sends a distinct `request_marker`, and all responses must carry
one marker from the submitted set, which only the stored row can satisfy. Checked
the assertion has teeth: making the incumbent branch echo the caller's own
metadata turns one returned row into 30 and fails the test.

* test: route ThreadSession inserts through the echoing base session

ThreadSession's scalars override returned a stub without .first(), so the
atomic create's INSERT..RETURNING read blew up in suites that stub threads
through it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Felipe Fidelix <felipe.fidelix@housecallpro.com>
Co-authored-by: ibbybuilds <mibrahim37612@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
F
Felipe Fidelix committed
e72c0f5459bc6deb2df6bdfc08077cdf5ce02281
Parent: 7b90688
Committed by GitHub <noreply@github.com> on 8/16/2026, 1:53:55 PM