Skip to content
CK/SYSTEMS
archived fullstack

Ultimate Economy Bot (UEBot)

Cross-server Discord economy with web dashboard

Role

Solo Developer

Timeframe

2024

Stack

C# .NET 7 Discord.NET Next.js React TypeScript MongoDB AWS ECS Docker GitHub Actions

What It Is

Ultimate Economy Bot (UEBot) is a Discord bot that lets online communities create their own virtual currency and economy. It provides points accounts, shops, ranks, and rewards to keep Discord servers active and fun. Target users are community admins and moderators – especially gaming or fan groups with multiple Discord servers – who want a unified economy across their servers. A gamer earns coins in one server and spends them in another, thanks to UEBot’s cross-server currency design.

Version History

UEBot evolved from an earlier open-source project:

Atlas Economy Bot (Open Source Predecessor)

The original “Atlas Economy Bot” was an earlier, simpler implementation that I released as open source. It provided basic economy features for single Discord servers.

Atlas Economy Bot - Discord Commands The Atlas Economy Bot showing various slash commands: /bal for balance checking, /baltop for leaderboards, /rankup for progression, and /settings for configuration

Atlas Repository: github.com/45ck/atlas-economy-bot

Ultimate Economy Bot (UEBot)

UEBot was a complete rebuild that addressed Atlas’s limitations:

  • Cross-server currency zones instead of single-server economies
  • Web dashboard for zero-command configuration
  • Clean Architecture with testable domain layer
  • MongoDB for flexible document storage
  • AWS ECS deployment for production reliability
  • 88%+ test coverage with comprehensive CI/CD

UEBot Web Dashboard The UEB Dashboard showing Currency Zone configuration - edit currency name, prefix, daily rewards, and invite rewards all from the web interface

UEBot Shops Management Shop item management interface for creating purchasable rewards

UEBot Rank System Rank progression configuration with customizable thresholds

UEBot Repository: github.com/45ck/UltimateEconomyBot

Problem & Constraints

Problem: Our Minecraft community ran several Discord servers and wanted a shared currency linking them. Existing economy bots were siloed per server. We needed to synchronize points across servers, with leaderboards and items, to increase engagement without enabling exploits (e.g. farming coins on one server to abuse another).

Key Constraints & Solutions

  • Cross-Server Currency: Introduced “Currency Zone” concept – an economy instance spanning multiple guilds. All accounts tied to a Zone rather than single guild. Prevented cross-zone transfers to keep currencies separate.
  • Closed-Loop Currency: Explicitly made it a closed-loop system with no real money conversion. UEBot points can’t be cashed out – avoids legal/ToS issues. Focuses on in-game perks rather than real rewards.
  • Data Consistency: Ensuring no race conditions or negative balances when 100 users earn coins simultaneously. Tested with simulated concurrent transactions – 100 parallel transfers resulted in no negatives or double spends.
  • Timeline: ~1 year to deliver a stable product. Used proven tools (Discord.NET, Next.js) and deferred nice-to-haves.

My Role

This project was my end-to-end responsibility:

  • Designed architecture (bot backend and web frontend)
  • Implemented core features and cloud infrastructure
  • Built from scratch: identifying need, developing solution, maintaining it
  • Wore multiple hats: product manager, backend developer (C# economy engine), frontend developer (React dashboard), and DevOps (CI/CD and deployment)
  • Wrote comprehensive documentation and testing

Outcome & Impact

UEBot successfully launched in late 2024:

  • Unified currency across 5 Discord servers (~2000 total users)
  • Members loved it: One global balance, cross-server leaderboard, trading items across servers
  • Engagement rose: Daily routines (claiming rewards, checking ranks), trading between servers like a mini economy
  • Zero major crashes or data losses over 6 months of active use
  • Consistent points ledger – few bugs promptly fixed with no major incidents
  • Thousands of transactions processed with average latency <200ms (well within 800ms budget)
  • Listed publicly on Top.gg with polished description
  • Project archived Dec 2024 after fulfilling objectives; concepts evolving into multi-tenant SaaS

Architecture

UEBot’s architecture follows a modular layered design, split into three main parts:

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  Discord Users  │────▶│  C# Bot Service │────▶│    MongoDB      │
│  (Commands)     │     │  (.NET 7)       │◀────│    Atlas        │
└─────────────────┘     └─────────────────┘     └────────┬────────┘

                        ┌─────────────────┐              │
                        │  Next.js Web    │──────────────┘
                        │  Dashboard      │
                        └─────────────────┘


                        ┌─────────────────┐
                        │  Discord OAuth  │
                        │  (Admin Auth)   │
                        └─────────────────┘

Discord Bot Service (Backend)

C# (.NET 7) application using Discord.NET library. Connects to Discord API via WebSocket gateway to listen for commands. When user runs /command, bot validates, updates database, and responds with Discord embed.

Clean Architecture: Core domain layer (User, Account, Transaction) independent of Discord. Services for each use-case (TransactionService, ShopService). Bot layer is just interface calling these services – business logic decoupled from Discord specifics.

Web Dashboard (Frontend)

Next.js (React) web app for admin GUI. Instead of complex bot commands, admins log in via Discord OAuth2 to manage everything. Dashboard communicates with MongoDB through secure API layer.

“Zero Setup Commands – Fully Dashboard Controlled” – admins configure everything through GUI, reducing errors and cognitive load.

Database & Shared State

MongoDB (document database) storing all persistent data. Single source of truth that both bot and dashboard share. Collections for User, Account, CurrencyZone, Shop, TransactionLog, etc.

Sub-Modules

  • Ledger Module: Core currency and accounts
  • Shop Module: Store items, purchases
  • Rewards Module: Invite tracking, daily rewards
  • Connectors: Discord (and future Slack support)

Multi-Tenant Design

Single bot instance serves many communities (tenants), each identified by a CurrencyZone. Database documents carry Zone/Guild identifiers for data segregation.

Core Technical Decisions

Multi-Server “Zone” Model

Introduced Currency Zone that can include multiple Discord guilds. All accounts tied to Zone rather than single guild. Truly shared balances with enforced rules (no transfers across zones). Map each Discord user to single internal User record so one person’s actions on any guild funnel to one account.

Database Choice – NoSQL vs SQL

Started with MongoDB for speed of development and flexibility. Document DB let us iterate on schema without lengthy migrations. Carefully structured to avoid inconsistencies – separate collections rather than nested documents. Coded defensive checks for atomic updates. Planned PostgreSQL migration for stronger consistency once features stabilized.

Web Dashboard vs Command-Only

Major UX decision to provide web dashboard instead of relying on Discord text commands. React/Next.js dashboard for intuitive UX. Trade-off was increased complexity (OAuth, secure role-based access, sync), but significantly lowered entry barrier for non-technical admins.

Clean Architecture & Domain Layer

Implemented using Clean Architecture principles (inspired by Uncle Bob’s onion architecture). Plain C# classes for models (UserModel, AccountModel, Transaction) with all rules in service methods without Discord or UI code. Made it much easier to test logic and will ease future platform integrations (Slack, etc.).

Closed-Loop & Security Decisions

Policy decision: closed-loop, non-monetary points system. No cash-out or external transfer functionality. Simplified security drastically – no KYC/AML concerns, no real funds to steal. Rely on Discord for authentication rather than separate login system.

Idempotency and Exactly-Once Commands

Operations idempotent where possible. TransactionService takes optional idempotency key (Discord interaction IDs) so same action received twice won’t apply twice. 24-hour reversal window for mistaken transactions – admins can “undo” within a day.

Infrastructure & Deployment

AWS Stack

  • Docker containers for bot and web app
  • AWS ECS (Fargate) – automatically handles scaling and restarting
  • MongoDB Atlas – hosted Mongo with network peering to AWS VPC
  • AWS Secrets Manager for credentials
  • CloudWatch for log aggregation

CI/CD Pipeline (GitHub Actions)

  1. Every push runs test suite
  2. On successful main branch build, Docker image built and pushed to AWS ECR
  3. ECS instructed to deploy new image
  4. Continuous deployment with minimal downtime (new task spins up before old drops)

Environments

  • Development: Separate MongoDB database
  • Production: Live bot environment
  • Ephemeral test environments: PR branches deployed to separate ECS service

Rollback Strategy

Each build produces versioned Docker image. If issue discovered, quickly redeploy previous image from ECR. Blue-green deployment on ECS – launch new task alongside old for health check, then switch.

Secret Management

Secrets (bot token, OAuth client secret, DB passwords) injected via environment variables at runtime from AWS Secrets Manager. Never hard-coded or logged. Regular rotation plan (~90 days for critical secrets).

Data Model

Key Entities

User: Discord user mapped to UserModel. One economic profile across all servers in a Zone.

CurrencyZone: Economy instance with settings (currency name, symbol, daily reward amount). Has many Guilds associated.

Guild (Discord Server): Each Discord server with settings (default channel, cached info). Links to Zone via ZoneID.

Account: User’s balance in particular zone. Links UserId and ZoneId with current Balance. Created lazily on first earn/spend.

Shop & ShopItem: Store with items. Three item types: normal items, role items (grant Discord role), delivery items (external webhook). Purchases recorded in ShopItemPurchase collection.

Transaction / AccountLog: Append-only log of balance changes. Stores AccountId, amount, type (Transfer, Purchase, DailyReward), timestamp. Audit trail for reversal support.

Invite Tracking: DiscordServerInvite and DiscordServerInviteUser collections track invite codes and referrals for invite rewards.

Metrics & Aggregates: Pre-aggregated metrics per server/zone (messages sent, active users) for dashboard analytics.

Storage Technology

MongoDB Atlas with unique indexes on important fields. Application layer enforces invariants. Designed for potential SQL migration with documented normalized schema.

Security

Authentication

Delegated to Discord via OAuth2. NextAuth.js with Discord provider. Bot token stored as environment secret, regularly rotated.

Authorization

Rely on Discord’s built-in roles for admin rights. Only users with Manage Server or Administrator can make economic changes. Cross-check user’s guilds and roles via Discord API.

RBAC within economy: Treasury role can mint currency, Moderator can issue refunds. ManagerRole collection checked before privileged operations.

Data Security

  • All inter-service communication via database (secured by auth and network rules) or HTTPS
  • TLS-protected database connection
  • No sensitive personal data stored (only Discord IDs and usernames)
  • Daily backups on Mongo Atlas
  • Restricted DB access to specific IPs

Abuse Prevention

  • Invite rewards only granted if invited user stays for period (track quick leaves)
  • Limited rewards per day per inviter
  • Rate limiting and cooldowns on commands
  • Frozen accounts for banned users
  • Comprehensive audit logging

Observability

Logging

Detailed console logging for every important action:

  • Command invocations: [INFO] User123 used /pay 50 -> User456
  • Operations: Updated account balance, Added new role to user
  • Errors with stack traces and user-facing Discord embeds

Dual logging (user-facing and internal) – no silent failures. Error embeds include link to support server.

Monitoring

  • AWS CloudWatch: Metrics on memory, CPU
  • Custom ServerMetrics: Daily counts per guild (messages, users, transactions)
  • MongoDB Atlas dashboard: Operation count, latency, etc.
  • UptimeRobot: External pinging of dashboard URL

Bot typically used ~100MB RAM, negligible CPU. CloudWatch alarms for CPU >80% or memory >512MB (never triggered).

Alerting

  • CloudWatch email on ECS task death
  • Atlas alerts for disk usage or error spikes
  • Discord-based alerting: errors posted to admin channel for real-time notification

Testing Strategy

Unit Testing

Extensive xUnit tests for C# backend. Mock repositories via Moq for fast, focused tests. Each service has corresponding test suite (TransactionServiceTests, ShopServiceTests).

Examples:

// TransactionServiceTests
PayBetweenAccountsAsync_ShouldTransferAmount
PayBetweenAccountsAsync_ShouldFailIfInsufficientFunds

~95% coverage on critical services (TransactionService, etc.).

Integration Testing

  • Tests with actual in-memory Mongo instance
  • Next.js API route testing with database
  • Consistency tests between domain model and database schema
  • ERD diagram cross-checks with repositories

End-to-End Testing

  • Automated scripts simulating multiple users on test Discord server
  • Scenario: User A invites B, B joins (triggering reward), A transfers to B, B buys item
  • Playwright browser tests for dashboard critical flows

Non-Functional Testing

  • Load testing: JMeter script for 100 concurrent transfers – no crashes, acceptable slowdown
  • Soak testing: 48-hour run with frequent operations – memory stable
  • Fuzz testing: Random Unicode in shop names to ensure no breakage

Coverage & CI

  • ≥90% coverage goal on core backend logic (~88% overall achieved)
  • Coverage reporter fails build if coverage drops below targets
  • Mutation testing (PIT for .NET) on TransactionService – ~75% mutation score
  • Requirement traceability mapping each functional requirement to tests

Performance

Bottleneck Mitigation

  • Database: Minimized writes on hot paths. Rewards given discretely, counts aggregated in memory. Indexed queries for fast lookups.
  • Discord rate limits: Simple message responses within limits. Bulk operations chunked. No DM spam.
  • Single-threaded event loop: Async/await throughout for non-blocking I/O.

Efficiency

  • Profile critical sections – rank-up and transfer logic are O(n) at most
  • Leaderboards use cached pre-sorted lists or MongoDB indexed sort
  • Heavy use of async/await for concurrent request handling
  • 50 concurrent transfer load test: all completed correctly with slight time increase

Resource Usage

  • Small container: 0.25 vCPU, 512 MB RAM
  • Typical: ~5% CPU, 100-150MB memory
  • Gateway Intents tuned to only needed events (members, messages)

Scalability

  • Design handles 50-100 guilds (10-20k users) on single instance
  • Bottleneck would be MongoDB writes – cluster handles thousands of writes/sec
  • Discord 2500 guild limit noted – sharding ready if needed
  • Internal limits: max 100,000 accounts per zone, paginated list commands

Measured Performance

  • p95 latency for key API calls: ~100ms (goal was <800ms)
  • Transfer completed: typically ~42ms
  • Dashboard pages load within 1 second (SSR + SWR caching)

UX & Accessibility

Discord UX for Members

  • Simple slash commands with descriptions: /bal, /pay @user amount, /shop
  • User feedback on every action with embedded rich messages
  • Lengthy outputs sent privately or paginated to avoid chat spam

Web Dashboard for Admins

  • Single-page React app with clean design (light/dark theme)
  • Key actions few clicks away: Ranks → Add Rank → Fill fields → Save
  • “Zero Setup Commands – Fully Dashboard Controlled”
  • Information architecture based on user interviews

Visual Design

  • Clean, professional look (Discord dark mode friendly)
  • Clear typography and spacing
  • Interactive feedback (drag highlights, save toasts)

Accessibility (WCAG 2.1 AA)

  • High contrast colors (text #DDD on dark background)
  • Full keyboard navigation (Tab, Enter/Space)
  • ARIA labels and roles for dynamic content
  • role="alert" on update confirmations
  • Tables with <th> headers, invisible labels on icons
  • Screen reader tested (NVDA)
  • prefers-reduced-motion respected

Responsiveness

  • Mobile-first design
  • Nav menu becomes hamburger on small screens
  • Tables become card lists or horizontally scrollable

User Guidance

  • On-page tips and tooltips
  • Support server link in bot /help command
  • FAQ on Top.gg page and website
  • Proactive info design reduces confusion

Error UX

  • Form validation with field highlighting and clear messages
  • Polite bot error responses: "❌ You don't have permission (need Treasury role)"
  • Consistent, plain English tone with emoji to soften

Dark Mode

  • Tailwind dark mode classes
  • Auto-detects user preference
  • Avoids blinding white screen when switching from Discord

Future Enhancements

Multi-Platform Support

  • Slack integration: Core is platform-agnostic, placeholders for Slack connectors
  • Web widgets: Embed leaderboards on community websites
  • Public API: OAuth-based access for external integrations

Scalability & Architecture

  • Discord sharding: Multiple bot instances for >2500 guilds
  • Dedicated backend API: ASP.NET Core service that both bot and web talk to
  • Worker service: Background jobs for webhooks and metrics
  • Horizontal scaling: Message queue (AWS SQS) for cross-service communication

SQL Migration

  • PostgreSQL for enforced constraints and atomic operations
  • Data migration tool (export Mongo → transform → import Postgres)
  • Complex analytics queries

New Economic Features

  • Loans and interest: Treasury lending with automatic repayments
  • Auctions: Bidding format for shop items
  • Taxes/fees: Periodic wealth taxes, universal basic income experiments

Advanced Features

  • Allied communities: Cross-tenant limited exchange (goods/services only)
  • Enhanced observability: Sentry error tracking, Grafana dashboards
  • Admin audit UI: Graphs of money supply, fraud detection alerts
  • Export/restore: One-click economy backup and cloning

UX Improvements

  • Interactive Discord UI: Buttons/dropdowns for shop commands
  • Dynamic autocomplete: /buy <item> with actual item names
  • Mobile companion app: React Native app for checking balance
  • Internationalization: Spanish and French translations

Outcomes

  • Unified currency across 5 Discord servers (~2000 users)
  • Zero major crashes or data losses over 6 months
  • ~88% test coverage with ~95% on critical services
  • <200ms average command latency (well under 800ms budget)

Need a workflow like this shipped properly?

Send the workflow, bottleneck, or delivery problem. I will tell you whether it fits a governed workflow audit, starter build, or implementation sprint.

Request consulting
Newsletter

Short notes on building AI agents in production.

One email when something worth sharing ships. No fluff, no daily cadence, no recycled growth-thread noise.

Primary use: consulting updates, governed AI workflow lessons, and major project writeups.