No framework, no package manager, no build step, no third-party libraries. Upload it to ordinary shared hosting and it works — because that is where the customers who need it already are.
A property team hears from buyers through portals, its own website, Facebook and Instagram ads, WhatsApp, walk-ins and the phone. Each channel has its own inbox. None of them talk to each other.
An enquiry sits in an ad account nobody opens until Friday. By then the buyer has visited two other sites.
Which portal produced bookings, not just enquiries? Without one record per lead, that argument is settled by whoever speaks loudest.
Spreadsheets have no permissions. A telecaller can read the whole pipeline, and a departing executive can take it with them.
Capture, scoring out of 100, an 11-stage pipeline, duplicate detection and merge, activity timeline, follow-ups, tags and custom fields.
RERA number, developer, price and area bands, configurations, amenities, possession date, image gallery — with per-project reporting.
Round robin, least-loaded-first and team round robin, driven by rules on source, project, city or hour of day.
23 modules × 89 distinct actions, 9 ready-made roles, 5 visibility scopes, plus per-user grants that need no new role.
WhatsApp via the Meta Cloud API and email over raw SMTP, both governed by a three-state readiness check, with a delivery log that records why anything was skipped.
Embeddable and hosted web forms with origin allow-listing and a honeypot, Meta Lead Ads webhooks, and bulk import with duplicate preview.
Dashboards, source and funnel reports, targets, per-person performance, saved views, and XLSX export of any list on screen.
Full audit log, in-app notifications, staff email alerts on new leads and upcoming follow-ups, and a cron sweep for time-based work.
The target is a ₹300-a-month cPanel account, not a Kubernetes cluster. That single constraint decided almost every technical choice below.
Where the build departs from the obvious approach, and why.
Every request asks two separate questions: may this role perform this action, and is this record inside the part of the organisation this person can see? Visibility walks the manager and team tree in code rather than a recursive query, so MySQL 5.7 is still supported.
WhatsApp and email report red, amber or green. Green requires a test send that actually landed. The server re-derives the verdict before every message, and a skipped message records its reason in words.
Spreadsheet export builds the ZIP container itself using gzdeflate, so no ext-zip and no PhpSpreadsheet. Values go in as inline strings, which also makes CSV-style formula injection inert.
A small client handles STARTTLS, implicit SSL, AUTH LOGIN and dot-stuffing. It is a few hundred lines against a library plus its transitive tree, and it fails with an error a support person can read.
Domain events queue during a request and flush after litespeed_finish_request(), so sending a welcome message never makes the user wait for a third-party API.
Integration credentials are sealed with AES-256-GCM derived from APP_KEY. Passwords are bcrypt and one-way. Session tokens are opaque and stored only as a SHA-256 hash.
Not mocked units. The suites sign in over HTTP, act as different roles, and assert what each one is allowed to see.
Multi-company isolation, hierarchy and assignment, project visibility, lead permissions, and the staff alert rules — each suite cleans up after itself.
Column names verified against the live schema, NOT NULL coverage on inserts, JavaScript import resolution, and dead-code detection across the front end.
One script stages the files, exports the data in dependency order, refuses to package if a secret is present, and writes a dated archive.
One database the customer owns, on hosting in their name, with an upgrade that is a file copy and a migration — no build server, no container registry, and no dependency that expires.