mirror of
https://github.com/block/buzz.git
synced 2026-11-08 10:21:46 +00:00
**Bug** Default channels are channels that new community members should join automatically. If the database could not list those channels—for example, because its connection pool was busy—an invite claim or an in-app admin add still admitted the member to the community. That member could then remain outside the default channels permanently. **Cause** Community admission was saved before channel joins started. If listing the channels failed, the relay logged the error and stopped. Retrying the invite or admin add did not help: the member already existed, so the relay skipped the joins. **Fix** Save a marker for unfinished channel joins in the same database transaction as admission. If listing or joining channels fails, keep that marker. Retry when the member next authenticates, claims the invite again, or is added again by an admin. One channel's failure does not stop attempts to join the others. Retries preserve the existing membership rules: - A member who leaves a channel during recovery stays out of it. - Work from an earlier admission cannot add channels or clear pending work after the member is removed and admitted again. Each admission has a unique marker, checked under a database lock. - A reconnect still checks whether the member allows the original admin to add them to channels. - Once recovery finishes, later connections do not enroll the member in newly designated default channels. The operator command `buzz-admin add-member` continues to add community membership only. **Limits and rollout risks** Recovery needs one of those later requests; there is no background retry timer. This change does not repair members missed before it was installed. Channel announcements and notifications keep their existing best-effort behavior. A failure after channel membership is saved can still lose an announcement; this change does not replay it. Migration 0084 adds an optional UUID column to `relay_members`. Apply it before running the new code. Older relays ignore the column. The migration has a five-second lock timeout, so it fails rather than waiting indefinitely for its table lock. It adds no triggers, functions, procedures, rules, foreign keys, or data backfill. --------- Signed-off-by: Helen Tian <htian@squareup.com> Co-authored-by: Flipper <1ef64189596befbc8b93f9021bff35ae5d02b155d9e05fc124bca7349927d597@buzz.block.builderlab.xyz> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Codex <noreply@openai.com>