Peer-to-Peer Gear Rental Marketplace

A Rails marketplace for equipment listings, availability-aware booking, split payments, deposits, messaging, and spatial search.

Challenge

The platform needed to prevent double-booking the same equipment for overlapping dates while handling platform fees, owner payouts, and refundable deposits. A small team also needed real-time messaging and booking updates without maintaining a separate SPA.

Solution

Used Rails with PostgreSQL tstzrange and GiST exclusion constraints to reject overlapping confirmed bookings at the database layer. Designed split payments and deposits with Stripe Connect, then implemented realtime updates and async work with Hotwire, Action Cable, and Sidekiq.

Result

Delivered a two-sided marketplace where double-booking is structurally prevented and payments, deposits, search, messaging, and notifications live in one Rails codebase.

Team

Small team, 12 weeks

Full-stack Rails, marketplace payments, and realtime features

Role

Handled booking integrity, Stripe Connect architecture, Hotwire realtime features, geospatial search, Sidekiq jobs, and Pundit authorization.

Moved core correctness into PostgreSQL constraints and background jobs while keeping the UX responsive with Hotwire.

Tech Stack

FrameworkRuby on Rails 7
DatabasePostgreSQL / tstzrange / GiST
PaymentsStripe Connect / Manual-capture Deposit
RealtimeHotwire / Turbo Streams / Action Cable
JobsSidekiq / Redis
AuthDevise / Pundit

Key Features

01

Database-enforced double-booking prevention

02

Stripe Connect destination charges and deposits

03

Realtime messaging and booking updates with Hotwire

04

Availability-aware geospatial search

05

Background payment, deposit, notification, and indexing jobs

Technical Highlights

Correctness in the Database

Used PostgreSQL range types and exclusion constraints so overlapping confirmed bookings are rejected by the database itself.

Three Money Flows Modeled Honestly

Separated rental fees, owner payouts, and manual-capture deposits instead of forcing them into a single charge.