EXP is a video game clan which has a community discord server with over 11,000 current members with a suite of custom discord bots.
Across the bots, there are lots of features that the members can take advantage of:
The bots are hosted on a VPS with a custom CI/CD solution which allows for rapid auto deployments and minimal down time.
Typescript
Bun
TursoDB
This project was the biggest production project I had worked on. As such, I had to take a lot into consideration when designing the architecture and the codebase.
Generally speaking, I practiced lots of production codebase concepts (consistent and detailed variable names, keep it stupid simple, separation of concerns, etc etc), and learned to think ahead with the code, ensuring it's easy to read, test, extract, etc, as it might need to be improved and updated in the future.
For example, I had originally use json files as local storage, but the code to handle that was embedded within one specific feature, which turned out to be a mistake, as I ended up extracting that logic into a custom class/functions. After that, I took extra care to think about whether to write global functions (making them easy to use in the future, but taking extra time to code), or to keep them within features (saving coding time, but increasing it if the functionality needs to be extracted in future features).
To put it simply, it taught me to consider the implications of coding something one way, rather than coding the first thing that comes to mind that works.
The original focus of these bots was the bank system. Users can donate gems to the clan, and the bot would keep track of their balance and would issue interest on an hourly basis.
It was important that this system worked well, as big issues end up costing the admins a lot of money, and could leave users unhappy.
One issue I came across was that when users would gift, the recipient might not receive the gift (but the sender was debited), or vice versa. I learned about database atomicty, and used database transactions for any features where balance was transferred.
The bots have two types of giveaways - clan and user giveaways. Clan giveaways would run a few times a day, and users would get the prizes from the clan admins. User giveaways were run by users, where other users could enter to win gems.
With clan giveaways, there were thousands of users who each had hundreds of entries, resulting in a massive array of user entries that would have to be shuffled, and then a user id would be selected. This original implementation was really slow and only worked fine for a few hundred users, but once there were multiple thousands of users, it could take up to 40 minutes to draw a winner.. I switched to storing the entries with a javascript map, with each user simply being a "entry" in the map, and a random number to select the winner which drastically reduced the time it took to draw.