One Real Estate CRM for the Desk and the Site Visit

A subscription-based property and lead platform built end to end — a Next.js dashboard for the office, a Flutter app for agents in the field, and Razorpay billing tying the commercial side together.

Services : Mobile App Development ServicesIndustry : Real EstateType : Software Development, Website Development, Mobile App DevelopmentClient : Confidential, India
About the Client

A Growing Brokerage That Had Outgrown Its Spreadsheets

Our client runs a property consultancy in India - residential resale, commercial leasing, and raw land, handled by a team that spends most of the working day away from a desk. When they came to us, the business was being run out of three spreadsheets, a shared Drive folder of property photos, and roughly a dozen WhatsApp groups. That combination had worked when there were four agents. At twenty-two, it had stopped working in a way that was costing them deals.

The specific breaking point was attribution. Two agents would unknowingly work the same inbound enquiry, call the same buyer within an hour of each other, and the client would find out only when the buyer complained. Property details lived wherever the agent who listed them had put them, so quoting an area or a price meant phoning a colleague. Nobody could answer a simple question like "how many active commercial listings do we have under two crore" without an afternoon of manual counting.

They asked us for a CRM. What they actually needed was two products that behave like one. Akoode built the entire thing: the PostgreSQL data model, the Node.js API, a Next.js dashboard for managers and back-office staff, a Flutter application for agents on site visits, real-time notification delivery over WebSocket, and a Razorpay-backed subscription layer so the platform could be sold on to other brokerages later. We ran it from discovery through to App Store and Play Store submission.

16

Feature Modules

Leads, properties, owners, groups, calendar, maintenance and more, built as one system rather than bolted together.

4

Property Categories

Residential, commercial, plot and land each carry their own field set and validation rules.

3

Platforms Shipped

Web dashboard, iOS and Android from a single API and one shared contract.

0

Duplicate Enquiries

Server-side lead ownership means one agent owns a buyer, and everyone can see who.

Project Info

Client

Confidential, India

Industry

Real Estate / PropTech

Use Case

Lead and property management with subscription billing

Solution

Flutter app, Next.js dashboard, Node.js API, PostgreSQL

Engagement

Fixed Cost

The Problem

The Data Existed. Nobody Could Reach It in Time.

None of these problems were dramatic on their own. A duplicated call here, a stale price there. What made them expensive was how they fed each other — because listings lived in one place and enquiries in another, no agent could verify anything while standing in front of a client, so they guessed, and every guess created a correction somewhere downstream.

Two Agents, One Buyer

Inbound enquiries landed in a shared inbox with no ownership rules. The same buyer regularly got called twice in a morning by colleagues who had no idea the other had already made contact.

Listings Nobody Could Trust

Property specs were split across spreadsheets, chat threads and photo folders. Agents quoting carpet area or asking price from memory were wrong often enough that the office had stopped trusting the sheet entirely.

Nothing Worked on Site

Every useful record was desktop-bound. An agent at a property who wanted to log a visit or pull a comparable had to call the office and wait, or write it on paper and re-enter it that evening - if they remembered.

Reporting Meant Counting by Hand

Basic pipeline questions took hours to answer because there was no single source to query. By the time a report existed it described a week that had already ended.

They didn't have a data problem. They had twenty-two people making confident decisions from information none of them could actually verify.

Project Objectives

Replace the Whole Workflow, Not Patch It

We were explicit with the client early on: layering software over the existing spreadsheet habits would just add a fourth place to look. The brief we agreed on was replacement. Everything an agent touches during a working day had to live in the new system by launch, or the old habits would survive alongside it and nothing would change.

01

One Record Per Property, Per Buyer

Establish server-owned records with explicit assignment, so a lead has exactly one accountable agent and a listing has exactly one authoritative version. Every downstream feature had to read from that, never from a local copy.

02

Full Capability in the Field

The mobile app needed to be a peer of the dashboard, not a viewer. Agents had to create listings with photos, log visits, capture notes by voice and update deal stages from a phone at the property.

03

Model Property Types Honestly

A shop, a two-bedroom flat and an agricultural plot share almost no attributes. Rather than force one flat form, we needed category-specific field sets that stay correct even when someone reclassifies a record later.

04

Make It Sellable as a Product

The client intended to license the platform to other brokerages. That meant plans, usage limits, billing cycles, coupons, proration on upgrades and self-serve subscription management from day one.

05

Ship to Both Stores Cleanly

The mobile app had to satisfy Apple and Google review on first submission, which shaped real architectural decisions - particularly around how subscriptions could and could not be sold inside the app.

The Solution

Built as One System With Two Front Doors

We treated the dashboard and the app as two views onto the same data rather than two projects that talk to each other. One PostgreSQL schema, one Node.js API, one contract. Where the platforms differ, they differ deliberately - the field app is optimised for one-handed use on a site visit, the dashboard for volume work at a desk - but neither owns state the other can't see.

01

Schema and API First

We modelled properties, leads, owners and subscriptions in PostgreSQL before designing a single screen, with per-category detail tables hanging off a shared property record. The Node.js API was built against that schema and frozen as a contract early, which let the web and mobile tracks run in parallel without drifting.

02

The Web Dashboard

Next.js and React for managers, back-office staff and administrators – bulk property entry, pipeline oversight, agent assignment, reporting and the full subscription and billing surface. This is where Razorpay checkout lives and where an account owner manages their plan.

03

The Flutter Field App

A feature-first Flutter codebase of roughly 108,000 lines across 439 files, organised into sixteen self-contained modules. Dio handles networking with a refresh-token interceptor; a shared pagination session drives every list; state stays deliberately close to the widgets that own it.

04

Real Time and Field Tooling

WebSocket delivery for in-app notifications with Firebase Cloud Messaging for push when the app is closed. On top of that came the things agents actually asked for: voice-dictated notes with on-device transcription, Google Places address lookup, and photo and video capture attached directly to a listing.

05

Hardening and Store Submission

Before release we moved auth tokens into the iOS Keychain and Android Keystore with a silent migration for existing sessions, hard-disabled verbose logging in release builds, locked App Transport Security to HTTPS, and added guards to the build scripts that refuse to produce a store binary from non-production configuration.

Core Features

What Agents and Managers Actually Use Every Day

Highlight 01

Lead Pipeline With Real Ownership

Every enquiry gets an owner the moment it enters the system, and that assignment is enforced by the API rather than by convention. Managers reassign from the dashboard; agents see their own book on the phone.

  • Server-enforced single ownership per lead
  • Stage transitions with full activity history
  • Field-level collaboration rules that match the web exactly
Lead pipeline board showing assigned agents and deal stages

Highlight 02

Property Records That Match Reality

Four property categories each carry their own attribute set, validation and area semantics, so a plot listing never asks for a bedroom count. Photos, floor plans and walkthrough video attach to the record itself.

  • Residential, commercial, plot and land field sets
  • Labelled photo groups with video support
  • Area handling that stays correct per category
Property detail screen showing category-specific fields for a commercial listing

Highlight 03

Voice Notes After a Site Visit

Agents record a note while walking back to the car and it lands on the record as searchable text. On iOS we wired a native Speech framework bridge; Android uses Google Cloud Speech-to-Text.

  • Record, playback and transcribe in one flow
  • Native iOS transcription via a custom platform channel
  • Text attaches straight to the lead or property
Voice note recording screen with live transcription on a property record

Highlight 04

Notifications That Arrive While It Still Matters

A live WebSocket connection updates the in-app notification centre without a refresh, and Firebase push covers the app being backgrounded or closed. Assignment changes and visit reminders reach the right agent in seconds.

  • WebSocket stream for in-session updates
  • FCM push with a dedicated high-importance channel
  • Deep links straight to the record in question
Notification centre showing new lead assignment and site visit reminder

Highlight 05

Subscriptions, Usage and Invoices

Plans, billing cycles, coupon validation, proration previews and usage metering all run through the platform. Razorpay handles collection on the web; invoices generate as shareable PDFs on the client.

  • Razorpay checkout with signature verification and webhooks
  • OTP-confirmed plan changes with proration preview
  • Client-side invoice PDFs with native share
Plan comparison and billing history screen from the web dashboard
Case Study

Chosen for a Product That Has to Stay in Sync

The deciding factor throughout was consistency. Two clients reading one API means the schema has to be the contract, not a suggestion - so we picked a relational store with real constraints, a single Node.js service in front of it, and Flutter for mobile so iOS and Android could not drift apart in behaviour. Real-time sits on WebSocket where the session is live and Firebase, where it isn't, because those are genuinely different delivery problems.

Mobile Application

A single Flutter codebase shipping to both stores, structured feature-first so each module owns its data, domain and presentation layers. Networking runs through Dio with a token-refresh interceptor and a shared paginated list session.

Flutter logo
Flutter
Tailwind logo
Tailwind

Web & Backend

Next.js and React for the dashboard, backed by a Node.js API that owns all business rules, assignment logic and billing state. Every client-facing decision is enforced server-side.

Nextjs logo
Nextjs
Tailwind logo
Tailwind
Node Js logo
Node Js

Data & Integrations

PostgreSQL holds the property, lead and subscription schema with per-category detail tables. Around it sit Razorpay for billing, Firebase for push, and Google Cloud for Places lookup and speech transcription.

Mongodb logo
Mongodb
Postgresql logo
Postgresql
Engineering Challenges

The Interesting Work Was in the Seams

Individually, a form and a billing page are solved problems. The real work was staying true across two clients - a schema surviving reclassification, billing behaving differently on iOS, an auth flow surviving a restart.

Architecture diagram showing web dashboard and mobile app sharing one API and database
Real Estate CRM Platform

Selling Subscriptions Without Breaking Apple's Rules

purchasesThe commercial model is a Razorpay subscription. Apple doesn't permit a third-party gateway for digital access in an iOS app, and in-app purchase would have split billing across two systems.

Our Approach

Razorpay checkout stayed on the web dashboard, with one platform gate suppressing every purchase path in the app behind a flag. A background poller reconciles state after Razorpay's webhook lands.

One billing source of truth across three platforms

Reclassifying a Property Without Stranding Data

Each property category writes to its own detail table. Changing a record's category after creation left the old rows orphaned - still attached, still returned by some queries, quietly wrong.

Our Approach

Every read path now keys attribute resolution off the record's current category, not whichever detail row it finds first. The category picker locks once a record exists, backed by regression tests.

Zero orphaned detail rows after reclassification

A Two-Stage Signup That Survives a Restart

Registration verifies a phone by OTP, then conditionally an email, with the token issued only at the end. An app killed mid-flow left users verified enough to be rejected, not enough to proceed.

Our Approach

Signup was rebuilt as a state machine that persists its stage, honours the backend's verification flag, and rehydrates on launch into exactly the step the user left, through to plan selection.

Interrupted signups resume where they stopped

Tokens in the Keychain, Without Signing Everyone Out

Session and refresh tokens sat in plain preferences storage, readable from a device backup or a rooted handset. A naive migration would have logged out every existing user.

Our Approach

Reads check encrypted storage first and fall back to the legacy location, migrating the value and deleting the plaintext copy on first access, alongside disabled verbose logging.

No plaintext tokens, no forced re-login
Results & Impact

From Three Spreadsheets to One System of Record

rollout,The clearest measure of success was behavioural rather than numerical. Within the first weeks after rollout the shared spreadsheets stopped being edited — not because anyone banned them, but because the app answered the same questions faster and agents stopped opening them.

BEFORE

Contested Enquiries

No ownership rules meant the same buyer was routinely contacted by two agents on the same day.

Listings Nobody Trusted

Property specs lived in spreadsheets, chat threads and photo folders that disagreed with each other.

Desk-Bound Records

Anything useful required being at a computer, so site visits generated paper that got re-entered later or lost.

Reports That Arrived Late

Pipeline questions took hours of manual counting and described a week that had already finished.

OUR SOLUTION

Server-Owned Assignment

The API enforces one accountable agent per lead, visible to everyone, changeable only by a manager.

One Property Schema

Category-aware records in PostgreSQL with photos, video and documents attached to the listing itself.

A Field App With Full Rights

Flutter app that creates and edits records on site, including voice-captured notes that transcribe to text.

Live Pipeline State

WebSocket updates and Firebase push keep every device current without anyone refreshing anything.

AFTER

Clear Accountability

Every buyer has one named agent, and the duplicate-contact complaints that prompted the project stopped.

Answers in Seconds

Filtering active commercial listings under a price ceiling is now a search, not an afternoon.

Work Logged Where It Happens

Visits and notes are captured at the property, so nothing depends on an agent's memory that evening.

A Product, Not Just a Tool

Plans, metering and Razorpay billing mean the platform can now be licensed to other brokerages.

16Modules Delivered

Leads, properties, owners, groups, calendar, maintenance, notifications and billing shipped as one connected product.

3Platforms Live

Web dashboard plus iOS and Android, all reading one API and one schema.

ZeroPlaintext Credentials

Tokens moved to Keychain and Keystore with a silent migration, and release logging hard-disabled.

Use cases

Where This Architecture Transfers

Strip out the property vocabulary and what remains is a pattern we've now built and hardened: field staff and office staff working the same records from different devices, with subscription billing and real-time state on top. That shape recurs across a lot of industries.

Property Management Companies

Tenancies, maintenance tickets and inspection visits follow the same field-plus-office split, with recurring rent instead of subscriptions.

Interior and Fit-Out Studios

Site measurements, photo documentation and client approvals captured on location and reconciled against a central project record.

Field Sales Organisations

Any team where enquiry ownership matters and reps work away from a desk gets the same benefit from server-enforced assignment.

Equipment Rental and Leasing

Catalogue records with category-specific attributes, availability, contracts and recurring billing map almost directly onto this model.

Inspection and Survey Services

Scheduled visits, on-site capture with photos and voice notes, then a generated report shared from the device.

Multi-Branch Service Networks

Franchise or branch operations needing per-location data separation, central oversight and plan-based access tiers.

Why Akoode

We Build the Whole Thing, Then We Ship It

Plenty of teams can build a screen from a design file. The value we added here was in the parts nobody specifies up front — the schema decision that prevents a data bug eighteen months out, the platform constraint spotted before it becomes a store rejection, the migration that changes how tokens are stored without a single user noticing.

One Team, Every Layer

Database, API, web dashboard and mobile app were designed together by the same team, which is why the two clients don't disagree about anything. Nobody had to reverse-engineer someone else's contract.

Security Handled Before Launch, Not After

We audited the build ahead of submission and fixed what we found — credentials out of plain storage, verbose logging disabled in release, transport security locked to HTTPS. Store guards now block a release binary built from development configuration.

We Know What Stores Reject

The payment architecture was shaped by App Store policy from the first design conversation rather than discovered during review. That decision saved the client an entire submission cycle.

We Chase the Bug to the Schema

When reclassifying a property left stale rows behind, we traced it to the data model instead of patching the display. The fix came with regression tests covering the exact case we found in QA.

Start Your Project

Start Your Real Estate or Field-Operations Platform

Send us what you're trying to build and we'll reply within one business day. The first call is about your data and your workflow — what records you keep, who touches them and where things currently break - not a sales pitch.
Reply Time
< 30 working minutes
NDA-Friendly
Signed before kickoff
IP Ownership
100% yours from day one
Security check *
= ?

Stay Informed with Thoughtful Innovation

Subscribe to the Akoode newsletter for carefully curated insights on AI, digital intelligence, and real-world innovation. Just perspectives that help you think, plan, and build better.