Skip to content

RABNEER/EstateFlow

Repository files navigation

EstateFlow CRM

Production-ready, mobile-first real-estate CRM. Built with Next.js 15, TypeScript, Tailwind CSS, shadcn/ui and Supabase. Designed for real estate teams who get leads from 36 Acre, MagicBricks, Housing.com, Facebook / Instagram Ads, WhatsApp and their own website — and need to call them in seconds, send property details in one tap, and track every interaction.

Highlights

  • Instant agent-to-lead bridge call — Twilio Voice rings the assigned agent first, then dials the lead and bridges them into a conference. Falls back to the next available agent if the first one doesn't answer.
  • Webhook lead intake with HMAC-SHA256 signature verification, round-robin / least-busy assignment and instant in-app notification.
  • One-click property photo sharing over WhatsApp / SMS / email with public share links.
  • Follow-up automation with templates, schedule, snooze and due notifications.
  • Inventory with photos, documents, availability state and matching to leads by budget, location and type.
  • Attendance with GPS, optional selfies and admin dashboard.
  • Social media calendar with idea / draft / scheduled / published states and AI caption helper.
  • Reports & dashboard — leads by source, agent call performance, follow-ups, shares, attendance summary.
  • Multi-tenant with Row Level Security — every table is scoped by organization_id and protected with RLS policies.
  • Dry-run mode for Twilio, WhatsApp, SMS and email so the whole flow can be exercised locally without spending a rupee.

Tech stack

Layer Choice
Frontend Next.js 15 (App Router), TypeScript, Tailwind CSS
UI kit shadcn/ui + @base-ui/react
Backend Next.js API routes + Server Actions
Database Supabase Postgres with RLS
Auth Supabase Auth
Storage Supabase Storage (property photos, documents)
Voice Twilio Voice (with TwiML & conference bridge)
Messaging Twilio WhatsApp / SMS adapter
Email Resend (preferred) or SMTP adapter
AI OpenAI-compatible adapter (caption / copy draft)
Hosting Vercel (frontend) + Supabase (backend)

Repository structure

estateflow-crm/
├── src/
│   ├── app/
│   │   ├── (app)/            # Authenticated app pages (mobile shell, dashboard, leads, …)
│   │   ├── api/              # Route handlers (REST + webhooks)
│   │   │   ├── webhooks/leads        # External lead intake
│   │   │   └── twilio/voice/*        # Twilio voice webhooks
│   │   ├── share/property/[slug] # Public property share page
│   │   ├── login/  signup/   # Auth pages
│   ├── components/           # UI components (shared, leads, properties, …)
│   ├── lib/
│   │   ├── db/queries.ts     # Typed Supabase queries
│   │   ├── services/         # callService, messageService, emailService, …
│   │   ├── supabase/         # Browser + server + service-role clients
│   │   ├── types/database.ts # Schema-mirroring TS types
│   │   └── validations/      # Zod schemas
│   └── …
├── supabase/
│   ├── migrations/           # Schema + RLS policies
│   └── seed/                 # Seed SQL (optional)
├── scripts/
│   └── seed.ts               # Programmatic seed (recommended)
└── .env.example

The service layer (src/lib/services/*) is deliberately decoupled from UI — no Twilio / WhatsApp / email calls live in components. Every service supports production mode and dry-run mode, switched per organization via integration_settings.dry_run_mode.

Getting started locally

1. Prerequisites

  • Node.js 22.x and npm 10.x
  • A free Supabase project (https://app.supabase.com)
  • Optional for live voice: a Twilio account with a phone number
  • Optional for live email: a Resend account

2. Clone & install

git clone https://github.com/<you>/estateflow-crm.git
cd estateflow-crm
npm install

3. Create the database

In your Supabase project SQL editor, run the migration files in order:

supabase/migrations/20260518000000_initial_schema.sql
supabase/migrations/20260518000001_rls_policies.sql

(or use the Supabase CLI: supabase db push)

4. Configure environment

cp .env.example .env.local
# Fill in NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY,
# SUPABASE_SERVICE_ROLE_KEY at a minimum.

5. Seed sample data

npm run seed

This creates:

  • 1 organization (EstateFlow Demo Realty)
  • 5 users — admin, 2 sales agents, 1 field executive, 1 social media manager (default password: Estate@123!)
  • 20 sample leads across all sources / statuses
  • 10 sample properties with images
  • Sample calls, follow-ups, attendance records and social posts
  • Default message templates

Login credentials are printed at the end of the seed run.

6. Run the dev server

npm run dev
# open http://localhost:3000

Sign in with admin@estateflow.dev / Estate@123!.

Scripts

Command Purpose
npm run dev Start Next.js dev server on :3000
npm run build Production build
npm run start Serve the production build
npm run lint ESLint
npm run typecheck tsc --noEmit
npm run seed Seed the demo organization, users, data

Deployment

Supabase

  1. Create a new project, copy the URL + anon + service-role keys.
  2. Apply the migrations from supabase/migrations/ in order (Supabase Studio → SQL Editor, or supabase db push).
  3. (Optional) Enable email confirmations under Authentication → Providers → Email.
  4. Create a public Storage bucket named property-media if you want to upload property photos through the app — image upload uses signed URLs.

Vercel

  1. Push this repo to GitHub.
  2. Import it on https://vercel.com/new.
  3. Add the env vars from .env.example in Project → Settings → Environment Variables. At a minimum:
    • NEXT_PUBLIC_SUPABASE_URL
    • NEXT_PUBLIC_SUPABASE_ANON_KEY
    • SUPABASE_SERVICE_ROLE_KEY
    • APP_PUBLIC_URL (set to the eventual Vercel URL, e.g. https://estateflow-crm.vercel.app)
  4. Deploy. Subsequent pushes auto-deploy.

After deployment, update the Integrations page inside the app and set Public app URL to your Vercel domain so property share links and Twilio webhooks generate the right URLs.

Twilio Voice setup

The app supports a fully functioning Twilio Voice bridge between an agent and a lead, with a fallback to the next agent and automatic call logging.

  1. In the Twilio Console, buy a phone number that supports Voice.
  2. Open EstateFlow → More → Integrations and fill in:
    • Twilio Account SID
    • Twilio Auth Token
    • Twilio phone number (E.164 format, e.g. +15551234567)
    • Twilio voice webhook base URL (your public origin, e.g. https://estateflow-crm.vercel.app)
  3. Toggle Dry-run mode off when you're ready to place real calls.
  4. The Twilio number's Voice & Fax config will hit:
    {APP_PUBLIC_URL}/api/twilio/voice/agent-prompt?callId=<call_id>
    {APP_PUBLIC_URL}/api/twilio/voice/dial-lead?callId=<call_id>
    {APP_PUBLIC_URL}/api/twilio/voice/status?callId=<call_id>
    
    These are created by the app — you don't need to configure them in the Twilio Console as long as your Twilio voice webhook base URL is reachable.

Local testing without a public URL

Use ngrok to tunnel to http://localhost:3000:

ngrok http 3000
# copy the https URL into Integrations → Twilio voice webhook base URL

Or simply leave Dry-run mode on — the flow will record everything in the calls and activities tables but Twilio won't be invoked.

Webhook lead intake

External platforms (36 Acre, MagicBricks, Housing.com, Facebook Lead Ads, Zapier, Make, your own forms) can POST leads to:

POST {APP_PUBLIC_URL}/api/webhooks/leads
Content-Type: application/json
X-Org: <organization_slug>
X-Signature: sha256=<hex(hmac_sha256(body, lead_webhook_secret))>

The webhook accepts both camelCase and snake_case keys. Example payload:

{
  "fullName": "Rahul Sharma",
  "phone": "+919999999999",
  "email": "rahul@example.com",
  "source": "36 Acre",
  "propertyType": "Apartment",
  "budgetMin": 7500000,
  "budgetMax": 12000000,
  "preferredLocation": "Gurgaon",
  "notes": "Looking for 3BHK near Golf Course Road"
}

Testing with curl

ORG=estateflow-demo
BODY='{"fullName":"Rahul Sharma","phone":"+919999999999","source":"36 Acre","propertyType":"Apartment","budgetMin":7500000,"budgetMax":12000000,"preferredLocation":"Gurgaon"}'
SECRET=$(psql "$SUPABASE_DB_URL" -tAc "select lead_webhook_secret from integration_settings where organization_id=(select id from organizations where slug='$ORG')")
SIG="sha256=$(printf %s "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $2}')"

curl -X POST "$APP_PUBLIC_URL/api/webhooks/leads" \
  -H "Content-Type: application/json" \
  -H "X-Org: $ORG" \
  -H "X-Signature: $SIG" \
  -d "$BODY"

On success the webhook:

  1. Inserts the lead with source normalized ("36 Acre"36_acre).
  2. Assigns it to an agent (round-robin / least-busy / manual based on integration_settings.assignment_mode).
  3. Records an activity and notifies the agent.
  4. Triggers the bridge-call automation (or simulates it in dry-run mode).

Testing in Postman

  1. Import the same URL.
  2. Use a Pre-request Script to set the signature header:
    const body = pm.request.body.raw;
    const secret = pm.environment.get("WEBHOOK_SECRET");
    const sig = CryptoJS.HmacSHA256(body, secret).toString();
    pm.request.headers.upsert({ key: "X-Signature", value: `sha256=${sig}` });

Roles & permissions

Role Can do
Admin / Owner Everything: invite users, manage roles, see all data, configure integrations
Sales Manager View / assign leads, manage follow-ups, view performance reports
Sales Agent See assigned leads, call, send property details, add notes & follow-ups
Field Executive Check-in / check-out, view assigned site visits, add visit notes
Social Media Manager Manage social calendar, create / schedule posts

Mobile-first UX

  • Bottom navigation (Dashboard · Leads · Properties · Follow-ups · More).
  • Large tap targets, WhatsApp-style quick action buttons.
  • Sticky CTA bars on lead and property detail pages.
  • One-tap call, WhatsApp follow-up and property share from the lead page.
  • GPS check-in works on any mobile browser that supports the Geolocation API (Safari, Chrome, Firefox).

Acceptance criteria checklist

  • Sign in / sign up
  • Admin can invite users & manage roles
  • Manual lead creation
  • Webhook lead creation with signature verification
  • Round-robin lead assignment
  • Bridge-call automation (Twilio + dry-run)
  • Call logs persisted with status, duration, recording URL
  • Agent-only views of assigned leads
  • One-click call / WhatsApp / SMS / email from a lead
  • One-click property share with public link
  • Property CRUD with multiple photos
  • Lead timeline (calls, notes, shares, messages, follow-ups)
  • Attendance check-in / check-out with GPS
  • Admin attendance dashboard
  • Social posts draft / schedule / publish
  • Dashboard CRM metrics + reports
  • Mobile-first responsive UI
  • Cloud-ready Supabase + Vercel

License

MIT.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors