Skip to main content
Case study · Building materials

Trumac Retail The dashboard runs the rest.

Trumac makes buying building materials simple for hardware stores across Mumbai’s western suburbs: the brands they ask for, in stock, with a salesman at the counter every week. Now its website is a storefront for the whole range, and one operations dashboard runs everything behind it: the rounds, the sales, the money, the promises, the team and the books.

5
roles, one dashboardfrom the salesman to the director, each on its own first screen
0
duplicate payments, by designevery write to Zoho searches for itself first
15min
from Zoho Books to the officethe whole book mirrored, refreshed on open
0.8MB
for the whole 3D herothe pipe bundle and its light, smaller than one photo
Read in sixty seconds
01Where they started
A template website that showed none of the stock. Zoho Books kept the accounts, and the work around them (the rounds, the promises, the cash in the field) ran through a shared sheet and the phone.
02What we built
A storefront website built on one idea, everything they sell seen end-on. Behind it, an operations dashboard that plans the rounds, tracks sales, collections and promises, logs every rupee in the field and keeps Zoho Books in step.
03What it does now
The director opens one screen at 8 a.m. Each salesman opens the day’s round on a phone. The office runs everything else from the same app, and the evening register writes itself.
01The problem

The books said one thing, the field another

Trumac keeps hardware stores across Mumbai’s western suburbs supplied with uPVC pipe, fittings, cable and switchgear from the brands their customers ask for, held in stock and brought to the counter on a weekly round. The business grew faster than its tools. The accounts were in Zoho Books, but the work around them was spread across a sheet and the phone: which store to visit today, what a counter promised, where the day’s cash was, which stores a new salesman takes over. And the website, a template, showed none of what Trumac stocks.

So we did not build a dashboard on top of the sheet. We built the operation around the books.

What changed
  • 01A template websiteThe whole range, seen end-on
  • 02Rounds worked out each morningEvery round planned before 8 a.m.
  • 03Promises noted on the phoneEvery promise tracked until it is kept
  • 04Cash reconciled at month endEvery rupee logged, in Zoho by evening
02The website

Everything they sell, seen end-on

The website is a storefront, not a shop: it shows the whole range and sends retailers to the sales team. A bundle of uPVC pipe, a cut cable, a carton of switch plates: end-on, they are all the same picture, packed circles. That one geometry is the whole site. The home opens on a 72-pipe bundle drawn live in the browser, and the scroll is a flight down one bore into the catalogue.

The Trumac website hero: a packed bundle of white uPVC pipes seen end-on, one lit crescent on each ring
  1. The Trumac website hero: a packed bundle of white uPVC pipes seen end-on, one lit crescent on each ring01 · At restThe bundle, lit from one low morning source, a bright crescent on every ring.
  2. Mid-flight: the camera has entered one pipe, the bore walls curving past, daylight at the far end02 · The flightScroll, and the camera enters one pipe: the bore, then daylight at the far end.
  3. Daylight at the end of the bore03 · ArrivalIt comes out onto the catalogue, every range laid out on one page.
  • Still first, scene secondA still of the bundle is the first paint. The live scene arrives behind it, so the page never waits on 3D.
  • Draws only when something movesAt rest the canvas renders zero frames and the GPU does nothing at all.
  • Steady on a mid-range phoneSix draw calls, about 25k triangles, pixel density capped. If iOS drops the WebGL context, the scene rebuilds once on lean settings.
  • Every browser gets the motionThe print lines, route map and footer run on CSS scroll timelines. Firefox and older Safari get the same clock from one small script.
03The operations dashboard

One app runs the operation

Five roles, one app, each opening on its own first screen. The director opens Morning. Each salesman opens Today on a phone. The office plans the week, works leads and promises, brings new salesmen on and hands them stores, and follows every rupee in the field until it is in Zoho.

What it runs
Sales
Rounds planned by day, leads through to won, orders, monthly targets and incentive slabs.
Collections
Two-tap capture at the counter, cheques cleared or bounced, the outstanding book by age.
Promises
Every date a store names: waiting, kept, came late or nothing came.
Money in the field
Cash and UPI in each pocket, hand-overs the office counts, the daily register.
The team
Accounts and roles, stores handed to a new salesman, attendance read off the work, tasks.
The books
Zoho Books mirrored every 15 minutes, written back only through guarded paths.
Trumac dashboard Morning screen: the day’s figures, salesmen on plan, attendance grid and a needs-attention list, amounts masked
Director · 8 a.m.

Morning

Since the last look: what Zoho received, what the field wrote, which promises fell due, what went quiet. Attendance is read off the work itself, not a check-in button.

  • Every tile a link
  • Attendance from the work
  • Needs attention, by name
Trumac dashboard on a phone: the salesman’s Today with target, incentive and the round in order, amounts masked
Salesman · on the round

Today, on the phone

The round in the order worth driving, each store with what it usually pays, and the day’s target and incentive on the same screen. Capture is two taps, with six seconds of Undo instead of a dialog.

  • Round, leads and tasks
  • Two taps, no dialog
  • Target and incentive, live
The week: every store on the day it is visited, by salesman, amounts masked
The week: every store on the day it is visited. Drag a store to another salesman, or to a new one, and the round follows.
04Under the hood

For the technical reader

Two Next.js 16 apps, two repos, one client. The website has no database at all: its facts are baked into the build. The dashboard mirrors Zoho Books in Postgres with the operation’s own tables on top (rounds, leads, promises, tasks, custody, targets) and writes back to Zoho only through guarded paths, each idempotent by construction.

How a rupee travels
  1. Zoho Books
  2. Sync, cron and on open
  3. Neon mirror
  4. Morning ranks the round
  5. Two taps on the phone
  6. Search, then post to Zoho

Every 15 minutes, or the moment someone opens the app on a stale book, the mirror refreshes contacts, open invoices and payments. Morning ranks every store from recency, promise state and payment habit. A capture lands in the register and the custody ledger in one transaction. The office posts it to Zoho with a reference number the app can find again, so a retry after a dead socket adopts its own work instead of paying twice.

  • Next.js 16
  • React Three Fiber
  • CSS scroll timelines
  • Neon Postgres
  • Drizzle ORM
  • Auth.js v5
  • Zoho Books API
  • Vercel Cron
The write path

Built to never pay twice

A duplicated payment in the books is the worst thing this app could do. Seven stages stand between a press on the phone and a row in Zoho.

  1. The register line and the custody ledger line are written together with a client key, so a double press or a retry writes nothing new. The day must be open: a closed register refuses money.

  2. Every register line is matched against the Zoho mirror by store, amount and payment-mode family. "UPI H", "UPI KVB" and a bank transfer are one family. A cheque is never matched: it has no payment until it clears.

  3. Who may post to Zoho is a flag on the user: never a salesman, never grantable to yourself. The write credential is a second Zoho client held by one module; the sync token can only read.

  4. With the write flag unset, every path runs (search, payload, audit row, activity line) and stops one instruction short of the POST. Production is the only place it is on.

  5. Every attempt searches Zoho for reference_number = TRUMAC-<entry id> before writing. A retry after a timeout adopts the payment it already made.

  6. Mode × salesman → Zoho deposit account is a table the admin edits. An unmapped mode refuses the push: a cash payment in the wrong account looks correct until the month closes.

  7. Posted means Zoho returned an id; ticked means the next sync read it back. If somebody deletes it in Zoho, the next sync clears the tick and says so on the activity log.

Spec sheet
15 min
staleness after which the book refreshes itself on open
3
cron runs a day (08:00 · 13:00 · 18:30 IST), one at a time
30 s
refresh on the live day board; a closed day freezes as a snapshot
5
things it may write to Zoho: a payment and four contact fields
15
ledger tables under audit triggers, plus every mirror table
5
roles, 18 capabilities, one matrix; nothing else compares a role
1,200+
tests in the dashboard; typecheck, lint and build on every push
0
runtime fetches on the public site: no database, facts baked at build
6
draw calls in the hero scene, ~25k triangles, 0 fps at rest
Security posture

The guards behind that write path, and the rest of the platform.

Authentication
Auth.js credentials with bcrypt and a JWT in an HttpOnly cookie. A proxy gate on every request, and a second guard on every page and server action.
Authorization
Five roles (salesman, sales head, office, backend office, superuser) in one capability matrix; a test fails on any role comparison outside it. Zoho write is a per-account permission on top.
Money integrity
A closed day is read-only for the field; a line the app has posted cannot be deleted here; an append-only activity log and an audit trigger on every ledger and mirror table.
Two credentials
The sync client can only read Zoho. The write client is a dedicated Zoho user, held by one module, dry-run unless a production flag is set.
Data
Neon Postgres in Singapore, nightly backup to R2 with an in-workflow restore drill. The site holds no data and sends one email per enquiry.
Start a project

Trumac got the storefront and the system.

If your business has outgrown the tools it started on, and your website could belong to anyone in your trade, tell us. We build the thing only you could have, and the machinery underneath it.

0/10 min characters

No spam. Your details stay between us: privacy policy.