Reject banned users at freebuff session endpoints so queueDepth stops flickering#533
Reject banned users at freebuff session endpoints so queueDepth stops flickering#533
Conversation
… flickering Banned bots with valid API keys were POSTing /session every few seconds and re-entering the queue between the 15s admission-tick `evictBanned` sweeps, making the user-facing queue counter jump between ticks. Add a terminal `banned` status (403, mirroring `country_blocked`) so banned accounts never create a queued row, and filter banned users out of `queueDepthsByModel` / `queuePositionFor` so the displayed position/depth stays stable.
Greptile SummaryThis PR fixes a Key changes:
One minor observation: the country-block check in Confidence Score: 5/5Safe to merge — the change is additive, well-tested, and doesn't touch any hot paths for non-banned users. All changed paths have unit tests; the new banned status is terminal at every layer (type, server, CLI) so there is no risk of an unhandled state. The NOT EXISTS subquery is structurally identical to the pre-existing evictBanned query that is already in production. Non-banned users see no change in behaviour. No files require special attention — store.ts warrants a look to confirm the intentional omission of banned filtering from the single-model queueDepth function (used for admission-tick observability after evictBanned has already run). Important Files Changed
Sequence DiagramsequenceDiagram
participant CLI as CLI (banned bot)
participant Handler as _handlers.ts
participant PublicAPI as public-api.ts
participant Store as store.ts
participant DB as Database
CLI->>Handler: POST /api/v1/freebuff/session
Handler->>DB: getUserInfoFromApiKey (fields: id, email, banned)
DB-->>Handler: { id, email, banned: true }
Handler->>Handler: resolveUser → { userBanned: true }
Handler->>Handler: countryBlockedResponse (if not blocked)
Handler->>PublicAPI: requestSession({ userBanned: true })
PublicAPI->>PublicAPI: if (userBanned) return { status: 'banned' }
PublicAPI-->>Handler: { status: 'banned' }
Handler-->>CLI: HTTP 403 { status: 'banned' }
Note over CLI: nextDelayMs('banned') → null<br/>Polling stops. Shows Account unavailable
Note over Store: Every 15s admission tick
Store->>DB: evictBanned() — removes lingering rows
Store->>DB: queueDepthsByModel() — NOT EXISTS banned
Store->>DB: queuePositionFor() — NOT EXISTS banned
Note over Store: Non-banned users see stable position/depth counters
Reviews (1): Last reviewed commit: "Reject banned users at freebuff session ..." | Re-trigger Greptile |
Summary
/api/v1/freebuff/sessionevery few seconds and re-queuing between the 15s admission-tickevictBannedsweeps, causing the user-facing queueDepth/position counter to jump between ticks.bannedsession status (HTTP 403, mirroringcountry_blocked) so banned accounts never create a queued row; CLI shows an "Account unavailable" screen and stops polling.queueDepthsByModelandqueuePositionForso the displayed position/depth stays stable even if a banned row briefly exists.Test plan
bannedwithout creating a queue rowrequestSession/getSessionStateshort-circuit onuserBanned🤖 Generated with Claude Code