NyumbaAI: AI-Powered Real Estate & Rental Platform
Inspiration
My journey as a software developer is rooted in solving real-world friction. When I received my admission letter to pursue my Bachelor of Science in Computer Science, I was called to a university far from where I stayed. Upon arrival, I faced an immediate crisis: all on-campus hostels were fully booked.
I was forced to hunt for off-campus housing in completely unfamiliar neighborhoods while simultaneously navigating mandatory university registration. I spent two exhausting days walking in areas I had never seen before, carrying my belongings under the hot sun, and struggling to find shelter.
As time went on, I watched fellow students face even worse outcomes:
- Theft and Lost Property: Freshmen carrying bags through unfamiliar areas late at night had their belongings stolen.
- Fake House Scams: Unscrupulous brokers exploited desperate students by demanding non-refundable deposits for phantom or fake listings.
- Double-Booking Chaos: Multiple students would pay deposits for the exact same vacant unit, leaving people stranded on day one.
With Kenya being a global leader in AI adoption, particularly among young people who rely on conversational search over static websites, I wanted to build a secure, intelligent, and scam-proof house-hunting platform: NyumbaAI. As I await my graduation this December, building this project serves as a key milestone in my life to ensure no student ever faces homelessness or fraud when seeking an education.
How I Built It
NyumbaAI is an end-to-end platform built with a modern, full-stack JavaScript architecture:
- Frontend: React 19 single-page application built with Vite, Bootstrap 5 UI, and
@paypal/react-paypal-js. - Backend: Node.js v20+ with Express 5 REST API handling transactions, auth, and AI workflows.
- Database: Neon Serverless PostgreSQL with SSL connection pooling.
- Mapping: Google Maps Embed API displaying dynamic property locations and coordinates[cite: 2].
┌─────────────────────────────────────────────────────────────────────────┐
│ React 19 Frontend (Vite) │
│ [ Explore & Filters ] [ Nixy AI Chat Drawer ] [ PayPal SDK ] │
└────────────────────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Node.js / Express 5 API Server │
│ [ Auth & JWT ] [ House Controller ] [ Lock Manager ] [ Lease Cron ] │
└───────┬────────────────────────────┬────────────────────────────┬───────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Neon Postgres│ │ Google Gemini AI │ │ PayPal REST API │
│ Database │ │ (2.5 Flash / SDK)│ │ (Orders v2) │
└──────────────┘ └──────────────────┘ └──────────────────┘
### Key Technical Pillars
1. **Conversational AI Assistant ("Nixy"):** Powered by Google Gemini 2.5 Flash using the `@google/genai` SDK and function calling. Instead of tweaking rigid UI sliders, tenants can chat directly with Nixy: *"Book house_1"* or *"Find a bed-seater near Westlands under KES 15,000"*.
2. **Secure Payments with PayPal:** NyumbaAI integrates PayPal Developer REST API v2 for deposit holds and rent payments. Verified escrow logic captures funds and confirms lease status only after webhook verification.
3. **15-Minute Concurrency-Safe Lock Architecture:** To eliminate the risk of double-booking, the backend applies an atomic pessimistic lock on `houses` table records (`locked_by` and `lock_expires_at`) when checkout begins.
Mathematically, if $S(h)$ represents the availability state of house $h$, $T_{\text{now}}$ is current time, and $T_{\text{hold}} = 900\text{ seconds}$ (15 minutes), the lock condition is defined as:
$$\text{Lock}(h) = \begin{cases} 1 & \text{if } S(h) = \text{AVAILABLE} \lor \left( S(h) = \text{LOCKED} \land T_{\text{now}} > T_{\text{lock\_expires}} \right) \\ 0 & \text{otherwise} \end{cases}$$
Upon lock acquisition:
$$T_{\text{lock\_expires}} = T_{\text{now}} + T_{\text{hold}}$$
If payment verification via PayPal succeeds within $T_{\text{hold}}$, the state updates to $S(h) = \text{BOOKED}$. If the lock expires without payment, $S(h)$ reverts automatically to $\text{AVAILABLE}$.
---
### Challenges I Faced
* **Gemini Model Availability & Rate Limits:** Utilizing free-tier Gemini API keys during high traffic resulted in frequent `503 Service Unavailable` or rate-limiting errors ($429\text{ Too Many Requests}$).
* *Resolution:* I designed a dual fallback system. I implemented exponential backoff retry logic on the backend and created a smart local natural language fallback engine. If the Gemini API key is missing or throwing rate limit errors, the system seamlessly transitions to local keyword-and-range parsing so house-hunting and booking never experience downtime.
* **Concurrency and Race Conditions:** Preventing race conditions when multiple users attempted to lock and pay for the same property required strict database row locking and timestamp checks before spawning PayPal orders.
* **Asynchronous Webhook State Sync:** Ensuring instantaneous frontend updates when a payment clears required syncing client UI state immediately after backend PayPal order capture callbacks execute.
---
### What I Learned
* **AI Resilience & Fallback Architecture:** Never rely solely on an external AI endpoint without a local fallback mechanism when building critical transaction flows.
* **Fintech Webhook Workflows:** Verifying PayPal REST API orders server-side guarantees accurate database transaction synchronization and prevents client-side tampering.
* **Automated Lifecycle Management:** Implementing background cron services (via Node.js and Resend API) to manage 5-day advance lease expiration warnings and auto-release properties back to public inventory.
Built With
- bootstrap
- express.js
- gemini
- google-maps
- javascript
- neon
- neondb
- node.js
- paypal
- postgresql
- react
- render
- vercel
Log in or sign up for Devpost to join the conversation.