Full-stack product · Realtime reservations

KudosCourts: keeping competing bookings in sync

KudosCourts is a live Philippine sports discovery and reservation product built across web and mobile. I designed its reservation lifecycle so players can request the same available time without falsely holding inventory, while one court-owner decision transactionally claims the slot, resolves competing requests, and updates affected views in real time.

A live personal product with web operation and a source-reviewed mobile application, owned end to end by Raphael.

Visit KudosCourtsLast reviewed

Project snapshot

Classification
Personal product
Status
Live web platform; mobile application source-reviewed
Period
January 2026 - Present
Role
Full-stack engineer
Platforms
Next.js web, Expo iOS/Android, shared TypeScript services

Evidence at a glance

Constraints

  • Several players can request the same available time, but a pending request must not falsely block everyone else.
  • Court, coach, umpire, and grouped reservations must resolve consistently when owners act concurrently.
  • Realtime screens must reflect committed database state across player, owner, detail, chat, and notification projections.
  • Web and mobile clients must share reservation meaning without duplicating backend lifecycle rules.

Attributable ownership

Designed and built the reservation domain, transactional inventory coordination, lifecycle events, realtime client reconciliation, owner and player workflows, web and Expo clients, notifications, and operational tooling.

Consequential decisions

  • Modeled a pending request as non-blocking intent, then made owner acceptance the transactional point that claims inventory.
  • Locked reservation targets before rows and retained PostgreSQL exclusion constraints as the final double-booking guard.
  • Separated transactional commands from read projections in a CQRS-style model, using minimal lifecycle events to trigger targeted React Query reconciliation.

Reliability and correctness

  • Deterministic target locking and database exclusion constraints prevent two accepted bookings from claiming overlapping inventory.
  • Accepting one request closes competing requests with explicit reasons; grouped reservations resolve all-or-nothing.
  • Realtime events signal change without becoming the source of truth, so React Query refetches canonical committed state.
  • Notification delivery remains best-effort outside the booking decision, preserving a successful commit when a provider fails.

Observable evidence

The live web product uses this lifecycle across player requests, court-owner acceptance, payment states, reservation detail, chat, and notifications; the source-reviewed Expo client maps the same domain without claiming an unverified store release.

01

What problem did KudosCourts solve?

Philippine sports information is fragmented across Facebook pages, maps, websites, group chats, and direct messages. Players struggle to compare venues, while owners often manage schedules and reservations through tools that were never designed for venue operations.

KudosCourts turns that fragmented information into searchable venue and coach discovery, then gives owners structured tools for listings, courts, schedules, prices, reservations, payments, staff, and notifications. Availability is presented only when a venue actually publishes and maintains it.

02

What did I own?

I carried the product from architecture through public operation: domain modeling, application code, ingestion, API contracts, owner workflows, web and mobile interfaces, notifications, developer integrations, deployment, and the operational tools needed to maintain the directory.

  • Public discovery across location, sport, amenities, reviews, photos, and pricing
  • Venue-owner operations for courts, schedules, availability, reservations, payments, teams, and notifications
  • Coach discovery and booking, open-play and game-room surfaces, and reservation chat
  • Typed developer APIs and external availability integrations
  • An Expo application spanning player, coach, and venue-organization modes
03

How does one booking safely win competing requests?

A pending request records intent without holding inventory, so several players can ask for the same available time. When a court owner accepts one request, a transactional command locks the target before reservation rows, rechecks availability, commits one valid outcome, and closes overlapping requests with an explicit resolution reason.

PostgreSQL exclusion constraints remain the final guard against overlapping accepted inventory. Multi-court reservation groups use the same coordinator and resolve together rather than leaving a player with only part of the requested booking.

One accepted booking, every affected view in sync

The booking decision commits before lightweight events tell affected screens what to refresh.

  1. 01Booking request
  2. 02Transactional claim
  3. 03Lifecycle event
  4. 04Targeted reconciliation
Inspect stage details
Booking request
A pending request records player intent without falsely holding inventory.
Transactional claim
Target locks and database constraints commit one valid booking outcome.
Lifecycle event
A minimal committed event identifies the reservation state change.
Targeted reconciliation
React Query refreshes only affected player, owner, chat, and inbox views.
04

How do player and owner views stay in sync?

The reservation model uses a pragmatic CQRS-style boundary: transactional commands own state changes, while player and owner screens read purpose-built projections. After a commit, lightweight lifecycle events identify what changed instead of trying to carry every derived view through the realtime channel.

React Query responds by invalidating only the affected reservation summaries, detail, linked booking, chat, alert, and notification keys, then refetches canonical state. Realtime improves responsiveness without becoming the authority for correctness when events are delayed, repeated, or missed.

05

How did web and mobile stay aligned?

The Expo client uses feature-level API adapters, Zod-validated responses, TanStack Query, and shared product concepts rather than duplicating backend rules. Contract snapshots and endpoint drift checks expose mismatches between the Next.js API and mobile mappings before they become silent runtime failures.

  • Typed Expo Router navigation for player, coach, and organization surfaces
  • Secure session storage, push notifications, deep links, and connectivity-aware query behavior
  • Realtime reservation chat plus mobile loading, error, empty, and offline states
  • A token-driven NativeWind component system with haptics, gestures, and Reanimated transitions
06

How does the product absorb existing venue data?

Ingestion remains a supporting capability rather than the primary proof. The system can normalize CSV, XLSX, ICS, and image-derived booking data into resumable drafts with row-level provenance, review, validation, and idempotent commit into availability blocks.

AI can infer constrained mappings for irregular source files, but owners review the draft and deterministic parsers and transactional services control the resulting availability changes.

07

What is the outcome?

KudosCourts is live as a national sports directory and reservation product. Its booking lifecycle turns concurrent player intent into one trusted court-owner outcome, then keeps affected web and mobile views current without making realtime delivery the source of truth.

The next measurement focus is practical product evidence: venue-data freshness, owner activation, booking conversion, mobile release quality, crash-free sessions, and performance. Those metrics will be published only when the underlying measurements are stable and reviewable.

Limitations and next steps

Honest limitations

  • Dynamic venue, court, city, booking, user, and release counts are omitted until supported by fresh authoritative measurements.
  • Availability is only as current as the venue-maintained data behind it.

Next evidence to establish

  • Measure competing-request resolution, event-to-view reconciliation latency, and booking conversion from stable instrumentation.
  • Validate mobile release quality through crash-free sessions and performance evidence before publishing release claims.

Verified technology

Next.js 16 · React 19 · TypeScript · Expo · React Native · tRPC · TanStack Query · Drizzle ORM · PostgreSQL · Supabase · Zod · QStash · OpenAI · Firecrawl · Crawlee