Introduction
Every IPL season, our team at Axelerant runs an internal prediction game. Colleagues pick match winners, answer bonus questions, and taunt and poke fun at each other on Slack; team loyalties are serious business in the cricket channel. We actually blogged about this some time ago.
What started as a fun hackathon project held together by Google Sheets and Zapier grew into something that needed a real rethink. This is the story of how we migrated from a fragile spreadsheet-driven architecture to a fully automated system powered by Supabase Edge Functions, AI, and a Slack bot with real personality.
The Old World: Google Sheets + Zapier
The original system was a classic hackathon product, stitched together from internal tools we already had: Google Sheets, Zapier, and a React frontend.
The flow was straightforward:
- Before each match, an automation posted a poll asking people to vote on the winner, along with a quirky bonus question.
- At match time, votes were collected and locked.
- After the match, an admin manually entered the result into the sheet. A wall of
VLOOKUP,COUNTIF, andIFformulas crunched the numbers and produced a leaderboard. - The frontend called the necessary APIs and displayed results on our leaderboard site.
Don't underestimate the complexity here. We often called this "Google Sheets programming" because that's exactly what it was: hundreds of formula cells with implicit dependencies, orchestrating scoring logic across multiple sheets. It worked remarkably well for almost five years. Not bad for a hackathon product.
The Bot Persona: Our 5-Year Long Experiment
Before we get into the technical migration, it's worth understanding the thing that actually makes this game special: the bot.
I'm a huge fan of dbrand's social media strategy, where every interaction feels like it's coming from a sentient, slightly unhinged robot. When I started building the automation and bot persona back in 2020, I wanted to replicate that energy for our game.
What we landed on: an evil but loyal alien minion, answering to "the Two Humans" (me and Prateek), unable to understand humans and their ways, sarcastic and funny, perpetually confused by cricket. That's a lot to unpack, I know. But we've been nurturing this hypothetical pet for half a decade, and the persona is half the reason to come back and see what new chaos has been unleashed on the Slack channel every day.
However, the old system could only live up to this personality through carefully written templates and somewhat overengineered message reply mechanics via Zapier automations. The bot sounded alive, but we always knew we could make it truly special. We always wanted the bot to actually be alive, to generate its own commentary, react to game events in real time, and have context and history, taunt and tease players by name when their teams lost. That was never possible with the old stack.
Why The Rewrite
Honestly, there was no real technical emergency. This is an internal game that runs for two months a year. After that, nobody really cares. The Google Sheets system worked, even if it had to be rebooted every year in a new sheet.
But both of us had been experimenting heavily with AI throughout the year, and we had built enough to know this could be done within a day or two max with our Claude, trusting it to architect and build things, of course, occasionally stopping it just in time before actual disasters.
Fair to say, we'd been itching to let our coding agents loose on this system; the prediction game was the perfect candidate in every way: complex enough to be interesting, low-stakes enough to be safe.
The challenge shifted from "how do we code this" to "what kind of system do we actually want to build", while still preserving the essence of the game that people love.
The Detour: An AWS Plan That Never Shipped
Our first instinct was to go full AWS. We planned an architecture with Aurora Serverless v2 (Postgres), Lambda functions, EventBridge for scheduling, API Gateway for the frontend, and SAM for infrastructure-as-code. Sound plan on paper.
But the complexity was absurd for what was, at its core, a fun internal game. VPC configuration, NAT gateways for Lambda-to-Aurora connectivity, Secrets Manager integration, cold start optimization, SAM template debugging, and the operational overhead would have consumed more time than the game itself.
We needed the power of Postgres and serverless functions without the infrastructure babysitting. That's when we turned to Supabase.
The New World: Supabase
Supabase gave us everything we needed in one platform:
- Postgres with full SQL support, RPC functions, and row-level security
- Edge Functions for serverless automation, deployable with a single pipeline
- pg_cron for scheduling, running directly in the database, no external scheduler needed
- Storage for everything else
- Dashboard for quick database inspection and debugging
- Zero infrastructure management, no VPCs, no NAT gateways, no cold start tuning
The migration wasn't just a database swap. It was a complete rethinking of how the game operates. The goal was simple: more bots, fewer humans.
The Hard Part: Migrating The Scoring Engine & the planning
One of the riskiest parts of the migration was ensuring scoring parity with the spreadsheets. The Google Sheets scoring logic was spread across hundreds of formula cells with implicit dependencies, the kind where changing one cell could silently break calculations three sheets away.
No matter which AI system you use, I highly recommend you always start a complex problem in plan mode. Here as well, we spent hours with Claude in planning, going over the fine details to have 100% confidence that Claude could one-shot it based on the plan.
We extracted the rules, implemented them as a standalone TypeScript module, and validated against historical match data. The new scoring engine handles all the edge cases that spreadsheets struggled with: matches where everyone picked correctly (everyone gets 1 point), matches with zero voters (no points awarded), revote multipliers stacking with odds calculations, and abandoned matches (no scoring impact).
Having scoring in code rather than formulas means we can write tests against it, debug it with logs, and modify it without fear. Every other piece of the system depends on scores being correct, so getting this right first was critical.
The Fun Part: Bots With Agentic Powers
With the infrastructure and scoring engine in place, we could finally build what we'd been dreaming about for years, bots that actually run the game.
We built 14 Edge Functions that collectively automate every aspect of the prediction game:
- Scheduling matches and posting questions
- Collecting and locking votes
- Waiting for matches to finish
- Detecting results automatically (search + scrape + AI extraction)
- Calculating scores
- Posting the leaderboard
- Generating engagement and marketing messages
Fully end-to-end autonomous capability. No human touches anything during normal operation.
The AI Engagement Layer
Perhaps the most fun addition is the AI-powered engagement bot that generates contextual messages throughout the tournament. The bot picks from several message types based on what's happening in the game:
- Climbers & Droppers: Who moved up or down the leaderboard after the latest match
- Contrarian Highlights: Celebrating players who went against the crowd and won big
- Taunts: Light-hearted ribbing of players on losing streaks
- Fan Banter: Commentary on IPL storylines mixed with prediction game context
- Match Spotlights: Highlighting dramatic scoring swings
Every message routes through an approval channel where a human can approve or reject it with an emoji reaction before it goes live. This keeps the bot entertaining without letting it go off the rails. AI-generated content aimed at real colleagues in a company Slack channel needs a human checkpoint. The pattern (bot posts draft → human reacts with ✅ or ❌) is lightweight enough not to be a burden but provides necessary oversight.
For the first time since we started the game, the Axelerant Prediction Pro Bot is genuinely alive. Players can interact with it, ask questions, and trash-talk each other through it. We finally built the persona we always wanted.
The Frontend: The Boring Migration (By Design)
The frontend migration was deliberately conservative, and that was the smartest decision we made. Truth was that the leaderboard was initially built in React, which I migrated to Next.js just last year, so the stack was already solid; at the max, it just needed a fresh coat of paint.
When I built the leaderboard, it was intentionally built in a way that we should be able to swap out the data source in the future. The React components had been integrated to consume flat data structures shaped like Google Sheets rows. Rather than rewriting every component, we built a new data adapter that queries the normalized Supabase tables and transforms the results into the same flat shapes the components already expected. The components didn't need to change at all.
Shape compatibility turned out to be a migration superpower. By decoupling the backend migration from the frontend migration, we eliminated an entire class of risk.
What We Gained
A full IPL season is roughly 70 matches, and the old system needed a human in the loop for every single one. Once the rebuild was live, we measured the difference across five dimensions: effort, reliability, multi-tournament flexibility, game mechanics, and auditability. Here’s where each one landed.
Zero Manual Work Per Match
In the old system, each match required an admin to verify the question was posted, check that votes were collected, enter the match result, enter the bonus answer, trigger score recalculation, and verify the leaderboard. That's 15–20 minutes per match, repeated 70+ times per season.
Now, the admin's only job is to occasionally approve engagement bot messages (a single emoji click) and intervene if auto-result fails on an unusual match, rain delays, super overs, and the like.
Reliability
Edge Functions run on Deno Deploy's edge network. pg_cron runs inside the database itself. There's no Zapier in the middle to silently fail, no rate-limited Google Sheets API to throttle under load. The system has been through a complete IPL season with near-zero manual intervention.
Multi-Tournament Support
The normalized database schema supports multiple tournaments out of the box. Switching from IPL 2025 to IPL 2026 is a database row change, not a spreadsheet duplication exercise.
Richer Game Mechanics
The automated pipeline enabled features that would have been impractical with the manual system: revote scoring with behavior-aware multipliers, AI-generated match previews, conversational bot interactions, automatic result detection, and engagement messages that reference actual game data.
Auditability
Every vote, score calculation, bot message, and result determination is logged in the database with timestamps. Players can audit any match's voting record through a Slack command. The approval workflow creates a clear trail of what was posted and who approved it.
What We Learned
- Starting with plan mode. The more solid your AI plan, the better chances you have for AI to do exactly what you want.
- Start with the scoring engine. Getting scoring parity with the spreadsheet was the hardest part of the entire migration. We should have extracted and validated the scoring logic before touching anything else. Every other piece depends on scores being correct.
- The approval workflow was essential. It would have been tempting to let the AI bot post directly to the channel. The approval step adds minimal friction but prevents the kind of AI-generated embarrassment that's hard to walk back in a company Slack.
- pg_cron is underrated. Having the scheduler inside the database eliminates an entire class of infrastructure: no EventBridge, no CloudWatch Events, no external cron services.
- Edge Functions have limits. Deno's runtime has a 150-second execution timeout on Supabase. The auto-result pipeline (search → scrape → AI extraction → scoring) occasionally bumps against this. We handle it with retry logic rather than trying to optimize the pipeline further.
- Shape compatibility is a migration superpower. By having the new data adapter return data in the same shape as the old Google Sheets adapter, we decoupled the backend and frontend migrations entirely. Components didn't care where their data came from as long as the property names matched.
The Real Migration Was Removing Humans From The Loop
What started as a "let's just move off Google Sheets" project became a ground-up rethinking of how an internal prediction game should work. The migration wasn't just a technology swap; it was a shift from a system that required constant human babysitting to one that runs autonomously, entertains players with AI-generated content, and handles edge cases gracefully.
The prediction game is more fun now. Not because the frontend changed dramatically (it didn't), but because the system around it is alive. It posts questions on time, collects votes reliably, detects results automatically, generates contextual commentary, and maintains a leaderboard that players actually trust.
If you're running an internal tool held together by spreadsheets and automation glue, the lesson isn't "use Supabase." It's this: the right migration isn't always the one that preserves your current architecture with better technology. Sometimes the best move is to reimagine what's possible when you remove the humans from the loop and let the bots take over.
FAQ'S
Supabase Edge Functions are serverless TypeScript functions that run on Deno Deploy’s edge network. In our rebuild they replaced the entire Zapier layer, 14 of them collectively automate scheduling matches, posting questions, collecting and locking votes, detecting match results via search + scrape + AI extraction, calculating scores, posting the leaderboard, and generating engagement messages. No Lambda, no API Gateway, no VPC.
Deno’s runtime on Supabase enforces a 150-second execution timeout per invocation. Our auto-result pipeline (search → scrape → AI extraction → scoring) occasionally bumps against this on long-running matches, and we handle it with retry logic rather than trying to optimize the pipeline further.
In our case, Claude operated in plan mode first; we spent hours iterating on the implementation plan before a single line of code was written. Then Claude executed the plan with us intervening only when it was about to make a recoverable mistake. The biggest unlock wasn’t code generation speed; it was that planning got cheap enough to do thoroughly, which is the part of software work that usually gets skipped.
If your spreadsheet has crossed the line from “spreadsheet” to “spreadsheet programming”, hundreds of formula cells with implicit dependencies across multiple sheets, then yes. Supabase gives you Postgres with RPC functions and row-level security, Edge Functions for serverless logic, and pg_cron for scheduling, all in one platform with zero infrastructure management. The migration is worth it the moment the spreadsheet starts requiring human babysitting.
We tried. Our first plan was Aurora Serverless v2, Lambda, EventBridge, API Gateway, and SAM. The operational overhead, VPC configuration, NAT gateways for Lambda-to-Aurora connectivity, Secrets Manager integration, cold start tuning, and SAM template debugging would have consumed more time than the game itself. For an internal tool that runs two months a year, Supabase’s zero-config Postgres + Edge Functions stack is the right call.
Every AI-generated message in our system routes through an approval channel where a human reacts with ✅ or ❌ before it goes live. The friction is one emoji click, light enough that it doesn’t become a bottleneck, but heavy enough that nothing makes it to the team channel without a human checkpoint. For AI-generated content aimed at real colleagues in a company's Slack, this approval step is non-negotiable.
Have an internal tool that's overdue for the same kind of rethink? Talk to us and we'll show you what one focused AI session can do on your stack.
Swarad Mokal, Technical Program Manager
Big time Manchester United fan, avid gamer, web series binge watcher, and handy auto mechanic.
Leave us a comment