Add Supabase persistence for members, violations & join requests (closes #1) - #19
Open
Kaaveh wants to merge 3 commits into
Open
Add Supabase persistence for members, violations & join requests (closes #1)#19Kaaveh wants to merge 3 commits into
Kaaveh wants to merge 3 commits into
Conversation
Replaces the in-memory _warnings dict in moderation with a Supabase-backed data layer so moderation state survives bot restarts. - New services/db.py: cached Supabase client plus helpers for warning counts, violation logging, member upserts, and join-request audit logs. Falls back to an in-memory counter when Supabase is unconfigured so the bot and tests still run without a database. - moderation.py: derive warning count from the DB and log each warn/mute/ban as a violation. - join_requests.py: record every approve/decline decision and upsert approved members for the audit trail. - admin_commands.py + main.py: add /violations <user_id> so admins can query a user's violation history. - infra/schema.sql: idempotent DDL for members, violations, join_requests. - Drop stale welcome_message assertions left over from the welcome refactor. Closes #1
- db.py: dispatch the synchronous Supabase calls through asyncio.to_thread so network I/O no longer blocks the bot's event loop; public helpers are now async and awaited by callers. - get_warning_count: add limit(1) so count="exact" no longer pulls back every matching row just to read the count. - moderation.py: decide the action, then record the violation before enforcing it, so the warning count advances even if a Telegram call fails and the read/record window stays small. - Update join_requests, admin_commands, and tests to await the async helpers.
Add Supabase persistence for members, violations & join requests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #1.
Moderation state currently lives in an in-memory
_warningsdict, so everywarning/mute/ban count is lost when the bot restarts. This PR introduces a
Supabase-backed data layer that persists moderation state and adds an audit
trail for member tracking and join-request decisions.
Changes
src/services/db.py— a Supabase data-access layer with helpers forwarning counts, violation logging, member upserts, and join-request audit
logging. The synchronous Supabase calls are dispatched via
asyncio.to_threadso DB I/O never blocks the bot's event loop.src/handlers/moderation.py— replaces the in-memory_warningsdict.The warning count is derived from the
violationstable, and eachwarn/mute/ban is recorded. The violation is written before enforcement so
the count advances even if a Telegram API call fails.
src/handlers/join_requests.py— logs every approve/decline decision tojoin_requestsand upserts approved users intomembers.src/handlers/admin_commands.py+src/main.py— adds an admin-only/violations <user_id>command to query a user's violation history.infra/schema.sql— idempotent DDL for themembers,violations, andjoin_requeststables (with indexes onuser_id).README.md— documents the db service, schema, and Supabase setup.tests/test_db.pycovers the fallback path; removed two stalewelcome_messageassertions intests/test_spam_checker.pythat werealready failing on the branch (leftovers from the merged welcome refactor,
now covered by
tests/test_welcome.py).Graceful degradation
If
SUPABASE_URL/SUPABASE_KEYare unset (local dev, CI), the bot stillruns: warning counts fall back to an in-memory counter for the lifetime of the
process. Persistence across restarts applies only when Supabase is configured.
No new dependencies —
supabasewas already inrequirements.txtand the envvars already existed in
config.py/.env.example.Setup
Apply the schema once: