Project not yet deployed — active development in progress. · প্রজেক্টটি এখনো রান করা হয়নি — কিছুদিনের মধ্যে রিলিজ করা হবে।
Under active development Bangladesh 🇧🇩 Bilingual · English / বাংলা Monorepo · 4 surfaces

Khelaw

Find a free slot. Book it in under a minute.

Khelaw is an indoor sports venue — turf, futsal, cricket, badminton — booking and management platform built for Bangladesh. Players see what's free near them right now and book it before anyone else does. Owners get every slot, payment and customer on one screen instead of a notebook and a ringing phone. খেলোয়াড়রা কাছাকাছি খালি স্লট দেখে এক মিনিটে বুক করতে পারবে, আর ভেন্যু মালিকরা সব বুকিং, পেমেন্ট ও কাস্টমার এক জায়গায় দেখতে পারবেন।

4
Client surfaces
87
Recorded decisions
8
Milestones (M0–M7)
2
Languages, 2 themes
The problem & the answer

From a notebook and a ringing phone, to one screen.

Privately owned turf venues in Bangladesh rent by the hour — and today the whole business runs on memory, WhatsApp and luck. Khelaw replaces that with a two-sided platform: a booking engine players can trust, and an operations console owners actually want to open. বাংলাদেশের ইনডোর টার্ফ ভেন্যুগুলোর জন্য একটি সম্পূর্ণ ডিজিটাল বুকিং ও ম্যানেজমেন্ট প্ল্যাটফর্ম।

Today

The old way

  • ✕Bookings tracked in a notebook, WhatsApp or memory — double bookings and forgotten slots are routine.
  • ✕Owners spend the day answering calls asking “is 9–10 PM free tomorrow?”.
  • ✕bKash / Nagad advances verified by hand, with no link between a payment and a booking.
  • ✕No data: which hours are dead, who the regulars are, what was earned this month.
  • ✕Players call several venues one by one, get no answer, and arrive to find the slot taken.
With Khelaw

The new way

  • ✓Real-time slot availability, held for 10 minutes while the player pays — no double bookings, by database constraint.
  • ✓Every request, payment and customer on one owner dashboard, with push + email the moment something changes.
  • ✓Manual bKash / Nagad / Rocket / Upay transfer with a generated reference — verified by a human, on both sides.
  • ✓Revenue, occupancy, peak-hour heatmaps and customer history — the data the notebook never had.
  • ✓One search, one map, one tap — see what's free near you and book it before someone else does.
For the player

“See what's free near me right now, book it in under a minute, and know instantly when it's confirmed.”

For the owner

“Every slot, every payment, every customer in one screen. No more double bookings. Fewer phone calls.”

One monorepo, four surfaces

Everything that makes the product work.

Four projects in one repository, each with a single job. The backend is the source of the API contract; the three clients are built against it.

backend/

Backend API

The booking engine, payments, subscriptions and notifications. The source of the OpenAPI contract every client is generated from.

Spring Boot 4 · Java 21 · PostgreSQL 16 · Cloudflare R2 · Brevo
web/

Player + Owner website

Search, slot board, checkout, and a full owner mode with calendar, requests, analytics and subscription billing — in one app.

React 19 · Vite · TypeScript · Tailwind · TanStack Query
admin/

Admin panel

Approvals, platform payment verification, subscription plans, coupons, catalog and moderation — the operations console.

React 19 · Vite · TypeScript · TanStack Table · Recharts
android/

Android app

Player and owner modes in one install — Compose screens, offline-tolerant caching, FCM push and QR check-in for the gate.

Kotlin · Jetpack Compose · MVVM · Hilt · Room
What it does

Built around the booking.

Every feature exists to move a slot from “free” to “confirmed” without a phone call, and to make sure the money and the game arrive at the same place.

🔍
Player

Search by sport, date & time

Filter by sport, price, distance, amenities and payment mode. Only venues with a court fully free for your whole range appear.

🗓️
Player

Live slot board

Morning / afternoon / evening / night groups, per-slot prices, and states for held, pending, booked and blocked. Updates over WebSocket.

⏱️
Player

10-minute checkout hold

Starting checkout reserves the slot so nobody else grabs it while you send money in bKash. A countdown is always visible.

💸
Player

Manual payment proof

A generated reference (KL7Q4M2X), the venue's wallet details, and a proof form. One transaction ID, one booking.

🎟️
Player

Ticket & QR check-in

Confirmed bookings become a ticket with a QR the venue scans at the gate. Status timeline, reminders, add-to-calendar.

✅
Owner

Requests inbox & verification

Expected amount vs. submitted amount side by side, the screenshot, and a duplicate-transaction check. Confirm, reject, or ask to fix.

📅
Owner

Calendar, offline bookings & blocks

Day and week views with a current-time line. Tap an empty range to add a phone booking or block. Closures ask before cancelling games.

📊
Owner

Analytics & customers

Revenue, occupancy, peak-hour heatmap, app-vs-offline split, repeat customers, no-show history and a private blocklist.

💳
Owner

Subscription & billing

1 / 3 / 6 / 12-month plans, coupons, grace windows and reminders. When it lapses the venue hides — the data never disappears.

🛡️
Admin

One platform payment queue

Application fees and subscriptions in a single queue. Approving a subscription payment activates the period instantly.

🏟️
Admin

Applications & venues

Approve, request changes or reject owner applications. Suspend, feature, and see reliability metrics for every venue.

✉️
All

Email, push & in-app — every update

Branded HTML email through Brevo, FCM push and an in-app centre. Every status change is sent on all three, in the user's language.

The heart of the product

A booking in five steps.

Nothing about a slot is decided by the client. The server generates it, prices it, holds it, and PostgreSQL guarantees it can only be sold once.

1
Pick a slot

Availability is generated from the venue's operating hours, closures, booking window and existing bookings.

2
Hold it

The server creates a 10-minute hold and returns the price breakdown, the advance amount and a payment reference.

3
Pay & submit proof

The player transfers to the venue's wallet using the reference, then submits sender number, transaction ID and screenshot.

4
Venue confirms

The owner checks the proof and confirms. The player is notified on every channel and gets a QR ticket.

5
Play & check in

The venue scans the QR at the gate. The booking auto-completes at the end time, and a review prompt follows.

Two rules before touching the code

Correctness is not a feature. It is the foundation.

These two rules are the reason the booking engine can be trusted. Everything else in the platform is built on top of them.

RULE 01

Double booking is prevented by PostgreSQL

Not by an application check. A GiST exclusion constraint on (court_id, time_range) covers holds, pending, confirmed and checked-in bookings — plus offline bookings and owner blocks, which live in the same table.

-- never replace with an application-level check ALTER TABLE booking ADD CONSTRAINT booking_no_overlap EXCLUDE USING gist (court_id WITH =, time_range WITH &&) WHERE (status IN ('HOLD','PENDING','CONFIRMED','CHECKED_IN'));
RULE 02

A slot belongs to the operating day it started on

A venue open Tuesday 15:00 → Wednesday 02:00 has its 01:00 slot on Tuesday. Every date filter, search query and availability response uses this — not the calendar date.

// venue open Tue 15:00 → Wed 02:00 01:00–02:00 on Wednesday → operatingDate = Tuesday // search "Tue 23:00–01:00" must match it
How it makes money

A per-venue subscription, not a cut of the game.

Khelaw never holds player money. Booking advances go straight to the owner's own wallet. The platform's revenue is a subscription the venue pays to stay listed.

1 mo
Entry plan
Full listing, booking engine and owner console.
Popular
3 mo
Quarterly
Everything in 1 month, at a lower monthly rate.
6 mo
Half year
Savings badge shown on the plan card.
12 mo
Yearly
Best per-month value, one payment a year.

How listing visibility works

A venue is visible to players only while all three are true:

  • the venue is ACTIVE,
  • its setup checklist is complete, and
  • a subscription period is active now (trial, paid or grace).

When it lapses, the venue disappears from home, search, map and booking — but confirmed bookings stay valid and owner mode keeps working, with a red banner to renew. No payment gateway, no escrow: every transfer is manual, with a generated reference, verified by a human.

Under the hood

A deliberately boring stack, used well.

Latest stable versions, PostgreSQL everywhere, and no service that a contributor has to install to run the project locally.

Backend

  • Java 21 · Spring Boot 4
  • Spring Web · Security (JWT) · Data JPA
  • WebSocket / STOMP · Actuator
  • PostgreSQL 16 · Flyway
  • btree_gist · cube · earthdistance
  • MapStruct · Lombok · ShedLock
  • springdoc OpenAPI · Swagger UI

Web & Admin

  • React 19 · Vite · TypeScript (strict)
  • Tailwind + shadcn/ui, custom design tokens
  • TanStack Query · Zustand · React Router
  • react-hook-form + zod
  • i18next (en / bn) · date-fns-tz
  • Leaflet + OpenStreetMap
  • @stomp/stompjs · Firebase JS SDK

Android

  • Kotlin · Jetpack Compose · Material 3
  • MVVM · Hilt · Coroutines + Flow
  • Retrofit + kotlinx.serialization
  • Room · DataStore · Paging 3
  • Navigation Compose · Coil 3
  • FCM · CameraX + ML Kit (QR)
  • WorkManager · Timber · Crashlytics

Infrastructure

  • Cloudflare R2 — public + private buckets
  • Brevo — transactional HTTP API
  • Redis — optional locally, required in prod
  • Firebase Cloud Messaging
  • GitHub Actions — 5 path-scoped workflows
  • Layered Docker image for the backend
  • gitleaks over the whole history
Where the build is

Eight milestones, end to end.

Each milestone is finished, tested and logged before the next one starts. The code for M0 through M6 is complete; M7 is the polish and hardening pass.

M0

Foundations

Project scaffolding, design tokens, i18n, Flyway baseline, health endpoint, themed placeholder home in EN/BN and light/dark.

Complete
M1

Auth, users, media, settings, catalog

Email OTP, JWT with rotating refresh tokens, multi-device sessions, devices & sessions screen, media upload, platform settings, sports / amenities / locations.

Complete
M2

Owner onboarding, payments, subscriptions

Owner application wizard, unified platform payments queue, subscription plans and listing visibility, coupons, venue setup checklist, mode switch.

Complete
M3

Availability & booking engine

Slot generation, after-midnight handling, booking window, price calculator, holds, state machine, offline bookings, blocks, check-in token, exclusion constraint and the 20-thread concurrency test.

Complete
M4

Player & owner booking UX

Home, search, map, venue details, slot board, checkout with countdown, my bookings, QR ticket, owner dashboard, requests inbox, calendar, phone booking and block sheets, QR scanner.

Complete
M5

Notifications, chat, reviews, favorites, reports

Notification channel matrix, all email templates in EN/BN, FCM push, notification centre, reminders, nudge, chat over REST + STOMP, reviews and replies, favorites, reports, admin moderation and broadcasts.

Complete
M6

Analytics, customers, staff, admin completion

Owner analytics and heatmap, customers and blocklist, staff invitations and roles, admin dashboard charts, users, booking search, audit log viewer, admin users and permissions.

Complete
M7

Polish & hardening

Full Bangla pass, dark mode, accessibility gates, performance budgets, query-count budgets, coverage gates, Playwright + Compose UI tests, Dockerfile, CI workflows and the final README.

In progress
Not code — humans

What's left before a public launch.

The application runs locally, but production needs accounts and credentials that only a person can create.

Deployment

The backend has not been deployed yet. The first production deploy is a milestone in its own right — after it, API breaking changes require a new version.

Domain authentication

SPF, DKIM and DMARC records for khelaw.site must be set up in Brevo, or transactional email will land in spam.

Credentials & keys

Cloudflare R2 buckets, the Brevo API key, the Firebase service account and google-services.json, and a Google Maps API key for Android.

Where the truth lives

Four documents, one source of truth.

The repository keeps its thinking written down. If you want to know why something is the way it is, the answer is in one of these files.

📘
docs/PROJECT_SPEC.md
The product specification

v1.4 — the single source of truth. Domain model, the booking engine rules, every feature per role, API design, architecture and the build plan.

📋
docs/PROGRESS.md
Milestone checklist

What is done, what is current, how to run everything, and every item that needs a human rather than an agent.

🧭
docs/DECISIONS.md
Every non-trivial decision

87 ADR-style entries with context, decision and consequence — including the mistakes, what caused them, and what now prevents them.

🤖
CLAUDE.md
Working rules & commands

The rules the agent works under, the commands to run each project, and a map into the spec.

🚧

Not live yet — but close.

Khelaw is being built milestone by milestone, and every piece of it has been tested against a real PostgreSQL database. It is not deployed to the public yet, and it is not open for sign-ups. A release is coming soon.

প্রজেক্টটি এখনো পাবলিকভাবে চালু হয়নি। ডেভেলপমেন্টের কাজ চলছে — কিছুদিনের মধ্যে রিলিজ করা হবে। তখন এই পেজেই আপডেট জানানো হবে।