Case study
Serendipity Scheduling App
A centralized scheduling web app and API for managing staff shifts and training sessions for a Roblox roleplay group.

Technology
- TypeScript
- React
- Node.js
- Express
- Tailwind
- Prisma
- MySQL
- Role
- Sole developer
- Year
- 2025
- Status
- In active use
Context
Replacing announcements and spreadsheets with one schedule
Serendipity Support Center is a Roblox therapy roleplay group where staff host shifts and scheduled training sessions. Before the app, there was no central schedule for shifts, so members often only knew one was happening after it had been announced. Training sessions were claimed by entering a username into a shared spreadsheet.
That workflow was easy to overwrite and depended on a high-ranking staff member manually resetting the spreadsheet each week. I built a single place where staff could create shifts or claim fixed training slots, while other members could see what was scheduled and when.
The system
One backend for the website and Roblox
The system paired a React frontend with an Express API backed by Prisma and MySQL, all hosted on a VPS. Staff signed in through Roblox OAuth 2.0, and their Roblox profile and group rank determined which scheduling actions they were allowed to perform.
Roblox game servers also communicated with the API over HTTP using an API key. This allowed scheduled and ongoing sessions to appear in-game, while the same backend supported smaller group features such as special nametags, rotating staff tips, and permission checks.
Main technical challenge
Rewarding the hours that needed hosts
When a staff member created a shift, the app calculated and displayed its Robux reward. Instead of assigning a fixed amount, I built a historical scoring model so that less frequently hosted time periods produced a higher reward.
The backend grouped previous shifts by time of week, weighted recent history more heavily, and combined the relevant periods when a shift crossed multiple time slots. The resulting score was mapped to a bounded Robux reward, with less frequently covered periods receiving stronger incentives.
The system also used a predictable fallback before enough history existed and applied the final result within the app's validation rules and weekly reward limits.
Designing that calculation was the hardest part of the project. It had to turn incomplete historical activity into an incentive that was useful to staff without making rewards unpredictable or disproportionately expensive.
Automation
Removing the weekly maintenance work
Scheduled jobs archived completed shifts into the history used by future reward calculations, removed expired shift records, and regenerated the fixed training slots for the new week.
This removed the need for a high-ranking staff member to reset the spreadsheet manually each week and preserved completed scheduling data instead of discarding it.
What I learned
Turning historical behavior into a useful signal
Building the reward system taught me how to turn incomplete historical activity into a practical scoring model. I had to structure past behavior, account for recency and limited data, define predictable fallback behavior, and keep the result useful within a real workflow.
It also reinforced that a technically correct calculation is not enough on its own. The output had to be understandable, bounded, and consistent enough for staff to trust and act on.