brackt/app/routes/api
chrisp 4a2f542fb1
All checks were successful
🚀 Deploy / 🔍 Lint (push) Successful in 50s
🚀 Deploy / 🐳 Build (push) Successful in 14m19s
🚀 Deploy / 🚀 Deploy (push) Successful in 11s
🚀 Deploy / 🧪 Test (push) Successful in 1m31s
🚀 Deploy / ʦ TypeScript (push) Successful in 1m21s
Fix Discord pick notifications silently dropped during autodraft chains (#57)
## Summary

- **Per-league queue**: replaced the single global notification queue with a \`Map<leagueId, queue>\` so concurrent drafts in different leagues drain independently and don't block each other
- **Deadlock fix**: wrapped the drainer loop in \`try/finally\` so \`drainingLeagues\` is always cleaned up even if a task throws unexpectedly — previously a crash would leave the flag set permanently, silently dropping all future notifications for that league
- **Wait cap fix**: moved \`Math.min\` to wrap \`(retryAfter * (attempt+1))\` so the 10s ceiling applies to the final product, not just the base value — settings actions that directly await webhook calls were previously blockable for up to 30s on a rate-limited third attempt

## Root cause of the original problem

During an autodraft chain, \`notifyPickMadeOnDiscord\` was called fire-and-forget for each pick in the chain, causing all webhook requests to fly concurrently. Discord's per-webhook rate limit (~5 req/2s) rejected most of them; the single retry logic fired for all simultaneously, hit the limit again, and the \`.catch()\` swallowed the errors silently.

## Test plan

- [ ] Enable autodraft for 5+ consecutive teams; trigger the chain; confirm all picks announce in Discord in order
- [ ] Confirm a slow/rate-limited webhook in League A does not delay League B's announcements
- [ ] \`npm run test:run\` — 158 test files, 2336 tests, all pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Chris Parsons <chrisparsons1127@gmail.com>
Reviewed-on: #57
2026-05-27 16:41:08 +00:00
..
__tests__ Add auto-start draft at scheduled time (#437) (#438) 2026-05-16 23:37:29 -07:00
autodraft.update.ts Migrate authentication from Clerk to BetterAuth (#324) 2026-04-24 22:00:49 -07:00
draft.adjust-time-bank.ts Migrate authentication from Clerk to BetterAuth (#324) 2026-04-24 22:00:49 -07:00
draft.force-autopick.ts Migrate authentication from Clerk to BetterAuth (#324) 2026-04-24 22:00:49 -07:00
draft.force-manual-pick.ts Show why a participant is ineligible to draft (#378) 2026-05-04 21:54:14 -07:00
draft.make-pick.ts Fix Discord pick notifications silently dropped during autodraft chains (#57) 2026-05-27 16:41:08 +00:00
draft.pause.ts Migrate authentication from Clerk to BetterAuth (#324) 2026-04-24 22:00:49 -07:00
draft.replace-pick.ts Show why a participant is ineligible to draft (#378) 2026-05-04 21:54:14 -07:00
draft.resume.ts Migrate authentication from Clerk to BetterAuth (#324) 2026-04-24 22:00:49 -07:00
draft.rollback.ts Add Brackt as a league-private meta-sport (#200) (#377) 2026-05-04 20:31:44 -07:00
draft.start.ts Add auto-start draft at scheduled time (#437) (#438) 2026-05-16 23:37:29 -07:00
queue.add.ts Migrate authentication from Clerk to BetterAuth (#324) 2026-04-24 22:00:49 -07:00
queue.clear.ts Migrate authentication from Clerk to BetterAuth (#324) 2026-04-24 22:00:49 -07:00
queue.remove.ts Migrate authentication from Clerk to BetterAuth (#324) 2026-04-24 22:00:49 -07:00
queue.reorder.ts Migrate authentication from Clerk to BetterAuth (#324) 2026-04-24 22:00:49 -07:00
seasons.$seasonId.draft.ts Canonical tournament layer: schema + backfill (1/2) (#365) 2026-05-01 20:13:18 -07:00
user.timezone.ts Add overnight pause for draft timers (#335) 2026-04-26 22:31:52 -07:00
watchlist.toggle.ts Mobile draft room improvements: watchlist, collapsible picks feed, autodraft controls (#355) 2026-04-29 11:49:26 -07:00