FlexRide – Car Rental Platform
FlexRide started as a three-week hackathon MVP built with a team ("Team Datadog") for a car rental business concept — React/Vite frontend, Express/Node backend, shipped fast to prove the idea worked. This is a solo, ground-up rebuild in Next.js: same business domain, rewritten architecture, and a much higher bar for correctness. Rather than porting the old code, I re-derived the business logic from the original app, closed bugs that had shipped in the hackathon version, and rebuilt every feature — guest and account reservations, Stripe payments, an admin dashboard, reviews, insurance add-ons, referrals, and smart recommendations — as a real, incrementally-verified product rather than a weekend demo.
- Client
- Personal Project
- Role
- Solo Full-Stack Developer
- Duration
- Ongoing solo rebuild
- Year
- 2026

Stack
Key Features
The Impact
payment race conditions found & closed
The Challenge
The hackathon version worked well enough to demo, but it carried real bugs: an admin self-promotion endpoint, a reservation-override flow that could silently drop a booking, and payment logic with no protection against concurrent double-submits. The challenge for the rebuild wasn't just re-implementing features — it was auditing every security- and money-adjacent path for the kind of bug that only shows up under real concurrent load, and fixing what I found instead of re-shipping it.
The Architecture
Next.js App Router throughout, with Server Components doing data fetching and Suspense isolating anything auth-dependent so the shell renders instantly instead of blocking on session checks. Auth is NextAuth v5 (Credentials provider) backed by MongoDB/Mongoose. Payments use a two-PaymentIntent Stripe pattern — a manual-capture deposit hold plus an auto-capture rental charge — with atomic findOneAndUpdate claims guarding both the checkout flow and referral-reward crediting against double-charge and double-credit race conditions. The data layer wraps reads in unstable_cache with granular tags, exposed through thin Route Handlers to a TanStack Query client. The admin dashboard is demo-safe: any authenticated user can browse it, but every mutation checks isAdmin server-side, with non-admins seeing disabled controls instead of a locked-out screen.
The Solution
Built incrementally, phase by phase, with every phase typechecked, linted, built, and verified live in a browser before moving on — not just checking that a build agent's summary sounded right. That verification pass caught real bugs after the fact, not just during initial development: two payment/referral race conditions found by reading the actual money-handling code path, a layout bug where the public navbar bled through and ghosted over the admin sidebar's logo on admin routes, and a full-page loading flash on the homepage and after logout caused by an auth check blocking the entire route instead of just the section that needed it.


The Results
Rebuilt the full hackathon feature set solo in Next.js: guest and account reservations, real Stripe payments, an admin dashboard, reviews, insurance add-ons, referral discounts, and rule-based recommendations
Found and fixed two real TOCTOU race conditions in live money-handling code — a Stripe double-charge path and a referral double-credit path — using atomic findOneAndUpdate claims
Closed three bugs inherited from the original hackathon build: an admin self-promotion endpoint, a reservation-override flow that could drop a booking, and unauthenticated write paths
Diagnosed and fixed a real UX regression: the homepage and post-logout flow were blocked on a full-page loading state caused by an unnecessary top-level auth() call; isolated it with Suspense so only the affected section suspends
Found and fixed a layout bug where the public site navbar visually bled through and ghosted over the admin dashboard's sidebar logo on /admin routes
