Building an event management platform sounds like “a booking website” until you map the real requirements: multi-step booking flows with deposit payments, vendor management with dependency tracking, client portal with real-time status, WhatsApp automation, and an admin dashboard with full operational visibility. This is the technical story of how we built rochevents.in for Roch Events.
The Problem We Were Solving
When Susmitha Rao (founder, Roch Events) came to us, the business was managed through WhatsApp groups and Excel files. Every booking was a manual WhatsApp conversation. Vendor payments were tracked in spreadsheets — leading to missed payments and disputes. Clients had no visibility into event preparation without calling. As the business grew, so did the chaos.
Core requirements: online booking system with Razorpay payments, vendor management with milestone tracking, client portal with real-time status, admin dashboard, and WhatsApp notifications throughout the process.
Architecture Decision: Monolith, Not Microservices
We chose a well-structured monolith. The Roch team would maintain this system long-term without dedicated DevOps expertise — a monolith is dramatically simpler to operate and debug than microservices. The system is organised into clear modules (Bookings, Vendors, Clients, Notifications) that communicate through defined interfaces, not shared database tables.
Stack: Next.js 13 (App Router) full-stack — public marketing site and all authenticated portals in one application. PostgreSQL on AWS RDS Multi-AZ. Prisma ORM for type-safe database access. AWS S3 for document storage. WhatsApp Cloud API for notifications. Razorpay for payments.
The Booking System: A State Machine
A booking moves through defined states: Enquiry → Discussion → Proposal Sent → Deposit Paid → Active Preparation → Completed (or Cancelled). Each transition triggers actions — emails, WhatsApp notifications, task creation for the Roch team.
We implemented this using XState (a JavaScript state machine library). Instead of scattered if/else logic determining valid transitions, all booking state logic lives in one declarative configuration. Benefits: impossible to accidentally create an invalid state transition, business logic is auditable in one place, adding new states or actions is surgical. State machine testing is also simpler — you test transitions in isolation.
Vendor Management: Modelling Dependencies as a Graph
Events have multiple vendors (caterer, photographer, decorator, entertainment). Some vendor deliveries depend on other vendors’ completions — the decorator needs the caterer’s confirmed menu before finalising setup. We modelled this as a directed acyclic graph (DAG) using a self-referential join table in PostgreSQL:
-- vendor_assignments
id, event_id, vendor_id, status, milestone_date, amount_paid
-- vendor_dependencies
dependent_assignment_id REFERENCES vendor_assignments(id),
required_assignment_id REFERENCES vendor_assignments(id)A recursive CTE query identifies blocked vendors and the dashboard highlights them with the reason for blockage. This replaced the most frustrating source of confusion in Roch’s operations — “I didn’t know X needed to happen before Y.”
Real-Time Client Portal: SSE Over WebSockets
We evaluated WebSockets for real-time updates but chose Server-Sent Events (SSE) instead. Reasoning: clients check the portal periodically, not constantly. SSE is simpler to implement, requires no WebSocket server maintenance, and works reliably through proxies. When a milestone updates, an SSE event pushes to all open client portal sessions for that event. The portal’s status timeline updates without a page refresh.
WhatsApp Integration Moments
We identified 12 key notification moments in the event lifecycle. Each has a WhatsApp template approved by Meta. The notification service subscribes to booking state transitions and vendor milestone updates, triggering the appropriate template for each event. Templates include: booking confirmation with event date and coordinator details, payment receipt with invoice link, preparation milestone updates (“Your floral arrangements have been confirmed”), and event-day reminders 48 hours and 2 hours before.
Critically, notifications go to both the client AND the relevant Roch team member — keeping everyone informed without anyone having to manually send status updates.
Razorpay Integration: Handling Partial Payments
Event bookings often involve partial payments — 30% deposit upfront, remainder before the event. We built a payment schedule system: each booking has a payment plan (defined in the proposal) with scheduled payment milestones. Razorpay Payment Links are generated for each milestone and sent via WhatsApp and email. Webhooks update payment status in real-time. The admin dashboard shows outstanding payments across all upcoming events with colour-coded urgency indicators.
Admin Dashboard: One View for Everything
The Roch team’s admin dashboard shows: upcoming events calendar, revenue tracking by month/quarter, vendor status across all active events, outstanding payments (overdue highlighted in red), and a notification log of all WhatsApp messages sent. Built with React + Recharts for visualisations, this replaced the 3+ separate spreadsheets and apps the team previously used.
Results After Launch
The platform went live after 3 months of development with 5 Vedhin engineers. Key outcomes: online enquiries increased significantly as the professional website and booking form gave potential clients confidence to enquire directly; the team estimated 15+ hours per week saved by eliminating manual WhatsApp coordination and Excel tracking; zero critical bugs reported in 90 days post-launch — our QA process included testing all 12 WhatsApp notification triggers, all payment scenarios, and all state machine transitions before release.
Susmitha’s review: five stars. “They actually delivered what they promised.” That’s the standard we hold ourselves to on every project.