Repcord
Personal projectA Discord bot that tracks and manages user reputation across servers. Members earn or lose rep through community interactions, peer endorsements, and moderation actions. Features a leaderboard system, configurable rep decay, role-based rep thresholds, and detailed analytics for server admins to understand community health and top contributors.
Key Features
- ●Peer-to-peer reputation system with /rep give and /rep revoke commands
- ●Configurable rep decay to prevent stale scores and encourage ongoing participation
- ●Auto-role assignment based on reputation thresholds: unlock channels and perks
- ●Per-server leaderboards with weekly, monthly, and all-time rankings
- ●Admin dashboard with reputation analytics, trends, and moderation history
- ●Anti-abuse system preventing rep farming with cooldowns and mutual-rep detection
The challenge
A large Discord server does not lack activity data. It lacks any way to tell contribution apart from volume. Message counts reward whoever talks the most, which is rarely whoever helps the most, and the member who answers three hard questions a week disappears next to the member who posts three hundred reactions. Moderators generally know who those people are, but that knowledge lives in the moderation team's heads, degrades as staff rotate out, and stops scaling the moment a server grows past the point where any one person reads everything. The cost shows up in permissions. Channels, perks, and roles that ought to be earned end up handed out by tenure or by whoever asks loudest, with no defensible record behind either. And any system built to fix that has to survive its own incentives, because the moment a score unlocks something real, some fraction of the community will optimize for the score instead of the behavior it was meant to measure.
The approach
Reputation in Repcord is peer-to-peer at the primitive level: /rep give and /rep revoke, awarded by members to members, with endorsements and moderation actions feeding the same ledger. Scores decay on a configurable schedule rather than accumulating forever, and that is the decision the rest of the design leans on. A permanent total measures who was helpful once; a decaying one measures who is helpful now, and it stops a long-dormant veteran from permanently outranking an active contributor. Decay also blunts farming, since standing bought cheaply does not stay bought. The remaining anti-abuse work is explicit: per-user cooldowns cap how often any single member can grant rep, and mutual-rep detection catches the reciprocal trade of two accounts endorsing each other in a loop, which is the most obvious way to manufacture standing. The storage split follows the access pattern. PostgreSQL holds the durable ledger, every grant, revocation, and moderation action, with the relational integrity that per-server history and audit trails require, while Redis absorbs the hot path of cooldown timers, rate limits, and leaderboard reads that would otherwise hit the database on every command in a busy server.
The outcome
What those decisions settle is how much a score is allowed to mean. Wiring thresholds to real access, so channels and perks unlock automatically as standing crosses each tier, is what makes reputation worth holding — and it is the same thing that guarantees someone will try to manufacture it, which is why cooldowns and mutual-rep detection are load-bearing rather than optional hardening. Decay carries a cost the design accepts on purpose: a contributor who steps away loses standing they genuinely earned, because the score is there to gate present access rather than to commemorate past service. The storage split has a consequence too. Revocations and moderation actions land in the Postgres ledger as recorded events rather than quiet subtractions, which is what lets the admin dashboard show history and trends instead of only a current number, and it leaves Redis as the disposable half, where losing the cache costs a refill rather than a record. The dashboard therefore answers a question most moderation tooling never asks: not only who broke a rule, but who is holding the community up.