## Tennis Khelo — Court bookings, ladders and coaching for a city's tennis scene. - URL: https://www.naveentehrpariya.dev/projects/tennis-khelo - Industry: Sports & Community - Client type: Product Company - Country: India - Role: Full Stack Product Engineer - Duration: 5 months - Status: Live - Live: https://tenniskhelo.com - Year: 2024 A platform that connects players, courts and coaches in one place, slot booking, skill-matched opponents, competitive ladders and academy management, all running off a single scheduling core. ### Problem Court bookings ran through phone calls and a WhatsApp group. Double bookings were routine, coaches had no way to publish availability, and casual players had nobody at their level to play against. ### Objectives - Remove double bookings entirely - Let coaches and academies manage their own schedules - Match players by skill so casual games are worth playing - Take payments online instead of at the gate ### Solution One scheduling engine backs every booking type (court, coaching slot and ladder fixture), so availability is computed once and cannot disagree between surfaces. Slot reservations take a short-lived Redis lock while payment completes, then commit to MySQL. Razorpay handles payment, and a rating system seeds ladder matchmaking. ### Features - Real-time court availability with conflict-free booking - Coach and academy schedule management - Skill-rated player matchmaking and ladders - Online payments with automatic refunds on cancellation - Tournament brackets and fixture generation - Owner dashboard for utilisation and revenue ### Stack - Frontend: Next.js, React, Tailwind CSS - Backend: Node.js, Express, Laravel, PHP - Database: MySQL, Redis - Cloud: AWS, Docker - Integrations: Razorpay, Twilio, Google Calendar ### Engineering challenges ### Two people tapping the same 6pm slot Problem: Peak-hour slots get several simultaneous requests, and an optimistic check-then-write leaves a window where both requests pass the check. Approach: A Redis lock is taken on the slot key before payment starts and released on success, failure or timeout, so exactly one request can ever reach the write. ### Cancellations that had to be fair to both sides Problem: Refund rules differed by how close to the slot the cancellation happened, and getting it wrong meant either angry players or angry court owners. Approach: Refund policy became a declarative rule set evaluated at cancellation time, so owners could change their own windows without a deployment. ### Outcome - Booking conflicts eliminated by moving reservations behind a single locked write path - Coaches gained self-service scheduling instead of routing every request through the venue - Court owners got utilisation visibility they previously had no way to measure ### What it taught Scheduling looks like CRUD until two people want the same minute. Deciding early that availability has exactly one owner saved every feature that came after it. Case study: https://www.naveentehrpariya.dev/projects/tennis-khelo More work: https://www.naveentehrpariya.dev/llms.txt