GO DESi's retail business runs on field sales. RSMs manage ASMs, ASMs manage Sales Officers and SOs cover beats and outlets. It's a deep hierarchy and it generates a lot of data. One Excel file alone runs past nine lakh rows and weighs 95MB.
Every level of that hierarchy needs the same kind of answer, fast. How is ASM Puneeth tracking against a target? Which SO had the worst week? Which outlets in JP Nagar haven't billed this month?
Every one of those answers is sitting in that file. Getting one out means opening it, waiting, building a pivot table, waiting again. The person who needs the answer is usually standing in a shop, on a phone, with four more outlets to cover before lunch.
So the problem was never unclear. What took time was working out how much I'd have to build to solve it properly, and the cheaper options came first.
The attempt that got closest
The best of the easy fixes was a custom GPT. The retail sales team loaded sales data into ChatGPT, set it up to answer questions against that data, and used it.
It worked well enough to prove the idea and badly enough to make the case for building properly. Four things broke it:
- Access. Not every ASM and RSM on the ground had a ChatGPT login, so the tool only reached the few people who did. That's the opposite of what a field tool needs to be.
- Scale. Nine lakh rows is far more than a chat interface can hold. The data had to be cut down to fit, so the answers were only ever about a slice of the business.
- Reliability. With no control over how a question got interpreted, numbers came back confidently wrong often enough that you had to go back to the spreadsheet and verify. That defeats the entire point.
- Security. Outlet-level billing, territory performance and individual SO numbers are sensitive. Anyone with the link had all of it, with no way to take that access away.
None of these are ChatGPT's failings. They're the limits of any general chat tool pointed at a database it doesn't own. Fixing them meant owning the whole path from question to number.
So that became the task. Same idea, different foundation: type a question in plain English, get the number in seconds. I called it RetailGPT.
Worth saying who "I" is here, since it explains some of what follows. I'm a CS graduate who joined GO DESi as an intern and stayed, drawn to the idea of working somewhere that wasn't a core tech company. Field sales is about as far from that as it gets, and the code turned out to be the easy half.
The mistake that taught me everything
My first version loaded all nine lakh rows into memory when the app opened. Roughly 900 API calls, and a four-to-eight minute wait before anyone could ask a single question.
Managers assumed it was broken and hit refresh, which made it worse. Nobody waits eight minutes for anything on a shop floor.
The fix was to invert the whole thing. Load nothing upfront except a list of names. When someone asks a question, work out exactly what they need, pull only that slice from the database, and calculate on the spot.
The app now opens in two to three seconds. Answers come back in three to five. And because the database does the work rather than the app, performance doesn't degrade as the data grows.
How a question gets answered
Every question takes two model calls, not one.
The first call understands it: who is being asked about, what time period, what metric. The second call answers it: pull the exact rows needed, hand those to the model, get back a clean response in rupees with no clutter around it.
Splitting the work this way is faster and more accurate than one large call trying to do both. Small and focused wins.
I also switched models mid-build, from GPT-4o to Claude. The deciding factor was specific and unglamorous. Claude was noticeably better at parsing Indian names and mixed English-Hindi phrasing, which is most of how our managers actually type.
Built for how people actually type
None of this came from a spec. It came from watching how people actually use the thing, which is where most of my assumptions went.
Field managers type fast, on phones, with typos. "Pooneeth" should still find Puneeth.
So name matching works in tiers. High-confidence matches get corrected silently. Medium-confidence gets a quick "did you mean Puneeth?" Low-confidence returns a shortlist to pick from. Two people with the same name? It asks which one, by role and territory.
The app also holds context between questions. Ask for MTD sales, then just say "what about last month?" and it knows what you mean.
Three decisions that mattered
Tag data to roles, not names. This one came from the sales team, not from me. Sales staff turnover is constant, and I'd have modelled the data around people because that's how the file was already structured. If the data says "ASM, Karnataka" instead of a person's name, whoever takes that role inherits the history automatically. No cleanup, no orphaned records, no gaps in a territory's history because someone resigned.
Suggested prompts do most of the work. Most managers tap a button rather than type. Behind a button labelled "MTD Sales" sits a query that adapts to whoever is logged in, so an RSM and an SO tapping the same button each get their own correct answer.
Access control, added after a wake-up call. During a training session I realised anyone with the link still had access, including people who had left the company. It was the same gap the ChatGPT version had, which is a humbling thing to find in my own build. Now: proper login, hashed passwords, access revoked the day someone leaves.
What it runs on
Streamlit for the app, Supabase (Postgres) for the database, Claude for language understanding, rapidfuzz for name matching. Hosted on Streamlit Cloud. About $30 a month.
What changed
The number that matters most is the one that doesn't move i.e. answer time stays at three to five seconds whether the database holds nine lakh rows or ninety, because the database does the work and the app only asks for the slice it needs. Every version of this that loads data upfront gets slower every month. This one doesn't.
WhatsApp access, automated morning reports, trend charts and outlet-level detail are all on the list. But the thing I set out to fix is fixed.
Nobody is waiting on a spreadsheet. They just ask.






