A full-stack co-living platform that connects property owners with tenants using AI-powered semantic search and vector-based roommate matching. Built with React, Node.js, MongoDB, Qdrant, and Google Gemini.
π Live Demo β co-living-two.vercel.app π API β co-living.up.railway.app
- π AI Semantic Search β search properties using natural language (e.g. "quiet pg near metro with wifi")
- π€ Roommate Matching β vector similarity matching finds compatible co-tenants
- β€οΈ Save Properties β bookmark listings to revisit later
- π Preference Survey β multi-step onboarding survey to capture lifestyle and budget preferences
- π Real-time Notifications β toast notifications for property activity
- πΊοΈ Property Map β explore listings on an interactive map
- ποΈ List Properties β create detailed property listings with photos, amenities and house rules
- ποΈ Manage Rooms β add individual rooms under each property with pricing and availability
- π Revenue Dashboard β visualise rental income over time
- π My Properties β manage all owned listings in one place
- π Firebase Auth β Google sign-in with phone OTP verification (Twilio)
- β‘ Redis Caching β sub-millisecond response times for hot queries
- π§ Gemini Embeddings β
gemini-embedding-001(3072-dim) vectors for semantic search - ποΈ Qdrant β cloud vector database for properties and roommate profiles
| Layer | Technology |
|---|---|
| Frontend | React 19, TypeScript, Vite, Tailwind CSS v4 |
| State / Data | TanStack Query v5, Axios |
| Auth | Firebase Auth, react-firebase-hooks |
| Backend | Node.js, Express 5, TypeScript |
| Database | MongoDB (Mongoose) |
| Cache | Redis |
| Vector DB | Qdrant Cloud |
| AI / Embeddings | Google Gemini (@google/genai) |
| OTP | Twilio Verify |
| Deployment | Vercel (frontend) Β· Railway (backend) |
Co-Living/
βββ frontend/ # React + Vite SPA
β βββ src/
β βββ api/ # Axios API wrappers per resource
β βββ components/ # Shared UI components
β βββ config/ # API base URL, Firebase, data config
β βββ context/ # UI context / provider
β βββ hooks/ # TanStack Query hooks
β βββ pages/
β β βββ Home/ # Dashboard, Profile, Owner view
β β βββ Login/ # Firebase Google sign-in
β β βββ Notification/ # Notification feed
β β βββ OnBoarding/ # Multi-step onboarding flow
β β βββ property/ # Browse, Detail, Create, Saved, Map
β β βββ userPropertyPriority/ # Survey, Roommate matching
β βββ services/ # Auth service, notification helpers
β βββ types/ # TypeScript types per domain
β
βββ backend/ # Express API
βββ src/
βββ config/ # Qdrant, Gemini, Firebase, Redis, env
βββ constants/ # UUID namespace
βββ controllers/ # Request handlers
βββ db/ # MongoDB connection
βββ middleware/ # Auth (Firebase JWT), Redis, Error
βββ models/ # Mongoose schemas
βββ routes/ # Express routers
βββ services/ # Business logic + embedding calls
βββ types/ # Zod schemas + TypeScript interfaces
βββ utils/ # Redis helpers, error utils
- Node.js β₯ 18
- MongoDB (local or Atlas)
- Redis (local or Upstash)
- Qdrant Cloud account
- Firebase project (Auth enabled)
- Google AI API key (Gemini)
- Twilio account (Verify service)
cd backend
npm installCreate .env in /backend:
PORT=5000
FRONTEND_URL=http://localhost:5173
MONGO_URL=mongodb://localhost:27017/co-living
REDIS_URL=redis://localhost:6379
# Firebase Admin SDK
FIREBASE_PROJECT_ID=your-project-id
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-xxx@your-project.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
# Twilio
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=your-auth-token
TWILIO_VERIFY_SERVICE_SID=VAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Qdrant
QDRANT_URL=https://your-cluster.qdrant.io
QDRANT_API_KEY=your-qdrant-api-key
# Google Gemini
GENAI_API_KEY=your-gemini-api-key
# Optional (OpenAI / Ollama fallback)
OPENAI_API_KEY=
OLLAMA_URL=http://localhost:11434/api/embeddingsnpm run dev
# Server starts on http://localhost:5000cd frontend
npm installCreate .env in /frontend:
VITE_BACKEND_URL=http://localhost:5000
VITE_FIREBASE_API_KEY=your-firebase-api-key
VITE_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your-project-id
VITE_FIREBASE_STORAGE_BUCKET=your-project.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=your-sender-id
VITE_FIREBASE_APP_ID=your-app-idnpm run dev
# App starts on http://localhost:5173All endpoints require a Firebase Bearer token: Authorization: Bearer <firebase_id_token>
| Method | Endpoint | Description |
|---|---|---|
POST |
/ |
Register or login β creates user if first time |
GET |
/me |
Get current user with populated profile |
POST |
/on-boarding |
Complete onboarding (name, role, DOB, phoneβ¦) |
POST |
/sendOtp |
Send OTP to phone via Twilio |
POST |
/verifyOtp |
Verify OTP and mark phone as verified |
| Method | Endpoint | Description |
|---|---|---|
GET |
/get |
List all active properties (Redis cached) |
GET |
/my |
Get owner's own properties |
GET |
/details/:id |
Get single property with owner info |
POST |
/create |
Create property β auto-generates embedding β upserts to Qdrant |
POST |
/search |
Semantic search via Gemini + Qdrant vector similarity |
| Method | Endpoint | Description |
|---|---|---|
GET |
/get |
All rooms sorted by rent (Redis cached) |
POST |
/create |
Create room under a property (Owners only) |
| Method | Endpoint | Description |
|---|---|---|
POST |
/create |
Save tenant preference β generates roommate embedding β upserts to Qdrant |
GET |
/get |
Get own preference profile |
PUT |
/update |
Update preference + re-embed |
GET |
/roommates |
Find compatible roommates via vector similarity |
| Method | Endpoint | Description |
|---|---|---|
PUT |
/update |
Update name, bio, email, phone, profile pic |
GET |
/saved |
Get saved properties |
POST |
/saved/:propertyId |
Toggle save/unsave a property |
| Method | Endpoint | Description |
|---|---|---|
GET |
/get |
Get all notifications |
GET |
/new |
Get unread notifications |
PUT |
/read |
Mark notifications as read |
When a property is created, the backend builds a rich text document from its name, description, type, location, amenities and rules. This is passed to gemini-embedding-001 to produce a 3072-dimensional vector, which is upserted to the properties collection in Qdrant.
When a tenant searches, the query string is embedded with the same model and compared via cosine similarity in Qdrant, returning the most semantically relevant properties β even if the exact keywords don't match.
User query: "quiet place near Koramangala with AC"
β Gemini embedding
β Qdrant cosine search (top 20)
β MongoDB fetch by propertyId
β Ranked results
After tenants complete the preference survey, a lifestyle profile string is built from their gender preference, work mode, food preference, occupancy type, pet-friendliness and preferred locations. This is embedded and stored in the roomMate Qdrant collection. The /roommates endpoint finds the top matching tenants by vector similarity.
A seed script is included to populate the database with realistic dummy data for development and testing.
Creates:
- 15 users (10 Tenants + 5 Owners with business profiles)
- 32 properties across Bengaluru, Hyderabad, Pune, Mumbai, Chennai, Delhi
- 50+ rooms (1β3 per property) with varied pricing and availability
- Property preference profiles for all 10 tenants
- Embeddings pushed to both Qdrant collections
Install dependencies:
pip install pymongo google-genai qdrant-clientRun:
python seed.pyThe script auto-deletes previously seeded data before each run. If Qdrant or Gemini is unreachable it falls back gracefully β Qdrant unavailability stores embedding metadata in Mongo, and Gemini unavailability uses deterministic mock vectors.
| Route | Page | Access |
|---|---|---|
/login |
Google sign-in | Public |
/on-boarding |
Multi-step profile setup | Authenticated, incomplete |
/home |
Dashboard β properties + rooms | Authenticated |
/home/browse |
Filter + explore all listings | Authenticated |
/home/property/details/:id |
Property detail + map | Authenticated |
/home/create/Property |
List a new property | Owners only |
/home/create/Room |
Add room to property | Owners only |
/home/survey |
Preference survey | Tenants only |
/home/preferences/edit |
Edit preferences | Tenants only |
/home/roommates |
Roommate matches | Tenants only |
/home/saved |
Saved properties | Authenticated |
/home/profile |
User profile | Authenticated |
/home/profile/edit |
Edit profile | Authenticated |
/home/owner |
Owner analytics | Owners only |
/home/messages |
Notification feed | Authenticated |
| Variable | Required | Description |
|---|---|---|
PORT |
β | Server port |
FRONTEND_URL |
β | CORS allowed origin |
MONGO_URL |
β | MongoDB connection string |
REDIS_URL |
β | Redis connection string |
FIREBASE_PROJECT_ID |
β | Firebase Admin |
FIREBASE_CLIENT_EMAIL |
β | Firebase Admin |
FIREBASE_PRIVATE_KEY |
β | Firebase Admin |
TWILIO_ACCOUNT_SID |
β | Phone OTP |
TWILIO_AUTH_TOKEN |
β | Phone OTP |
TWILIO_VERIFY_SERVICE_SID |
β | Phone OTP |
QDRANT_URL |
β | Vector DB URL |
QDRANT_API_KEY |
β | Vector DB API key |
GENAI_API_KEY |
β | Gemini embeddings |
OPENAI_API_KEY |
β | Optional alternative |
OLLAMA_URL |
β | Optional local embeddings |
| Variable | Required | Description |
|---|---|---|
VITE_BACKEND_URL |
β | Backend API base URL |
VITE_FIREBASE_* |
β | Firebase client config (6 vars) |
- Connect your GitHub repo to Vercel
- Set Framework Preset to
Vite - Set Root Directory to
frontend - Add all
VITE_*environment variables - Deploy
- Create a new Railway project
- Connect your GitHub repo
- Set Root Directory to
backend - Add all backend environment variables
- Railway auto-detects Node.js and runs
npm start
Ensure FRONTEND_URL in Railway matches your Vercel deployment URL for CORS to work.
MIT β see LICENSE