Skip to work
Melbin Kuriakose
Back to work
F

Filarity

A retail operating system for Indian shops

  • Product
  • UX
  • UI design
  • Full-stack
  • Solo
  1. Sale
  2. Stock
  3. Purchase
  4. Expense
  5. GST
  6. Profit

Most billing apps stop after the first box. Profit is only true once all six are in one ledger.

5
user roles designed for
24
database tables
~77
API endpoints
1
person built it
My role
Product, UX, UI and the full-stack build
What it is
A retail operating system for Indian shops
Designed for
One real saree shop, then generalised
Status
Live, used daily at a working counter
Filarity invoice list - GST bills with payment status, PDF and WhatsApp actions

Where it started

This began at a counter, not on a whiteboard

The first version was built for one real business - a saree shop billing customers at a counter. Everything in the product came from watching that shop work.

Before Filarity

Bill book

Sales

Notebook

Stock counted by hand

Excel

Purchases

Shopify

Online orders

WhatsApp

Expenses

The accountant

GST

“So how much did the shop actually make this month?”

Six places to look, and no single answer.

TL;DRNot a hypothetical SaaS idea. A real shop that could not tell you what it earned.

The problems

Four problems, and a design response to each

Every one of these is a business problem before it is a software problem.

The numbers lived in four places

Why it matters
Nobody could answer the only question that matters: what did the shop earn this month?
Design response
One ledger, and a dashboard built around the question rather than the tables.

Selling online and offline meant counting twice

Why it matters
Two stock counts drift, and the customer is the one who discovers the oversell.
Design response
Every channel writes to one inventory number - counter, Shopify and purchases alike.

GST was a monthly scramble

Why it matters
Credit claimed from memory is credit that may have to be paid back.
Design response
Purchases reconcile against GSTR-2B, and blocked credit folds into cost price instead.

Off-the-shelf tools did not fit

Why it matters
Accounting software assumes an accountant; billing apps stop at the invoice.
Design response
Model the whole money loop, so profit means revenue minus everything.

The people

Five people use this, and they want different things

Pick one to see what they came for, and what the product deliberately keeps from them.

“I need to know whether my shop is actually making money.”

Primary tasks

  • Dashboard
  • Profit
  • Expenses
  • GST

Sees

Everything, including cost price and margin.

Never sees

Nothing.

The interface hides what a role should not see. The server refuses it regardless - the UI is not the security boundary.

Information architecture

Navigation grouped by the question, not the table

The challenge was never fitting more features into a menu. It was finding a mental model that matched how the shop already operates.

The navigation is grouped by the question a shop is asking, not by the database table underneath. The hard part was never fitting more features into a menu - it was finding a mental model that matched how the shop already thinks about its day.

Design

How the experience was arrived at

Observe, ship something small, then let daily use at the counter decide what comes next.

  1. 01

    Observe

    Watched what actually happened between a customer picking a saree and the shop knowing whether it made money on it.

  2. 02

    Map

    Wrote down where every number lived, and which of them nobody could reconcile.

  3. 03

    Ship the smallest useful thing

    Version one did one job: type a bill, see it render, print it or send it on WhatsApp. It was at the counter before stock, purchases or GST existed.

  4. 04

    Follow the money outwards

    Invoices gave revenue. Purchases gave cost and stock. Expenses gave the rest. Only then did a profit number mean anything.

  5. 05

    Refine against daily use

    Everything after version one was added because real use at the counter exposed the next gap - not because it was on a roadmap.

  6. 06

    Generalise into a product

    Accounts, trials, subscriptions, an admin console, and a public read-only demo so anyone can walk the real app without signing up.

Billing, as the cashier experiences it

Seven steps, and a decision is needed in only three of them.

Scan or pick

Barcode at the counter, or search by name. Stock and price come with it.

Seven steps, and the cashier makes a decision in only three of them. Everything tax-shaped happens without being asked about.

Design principles

Six rules the product is actually held to.

01

Don’t make the shop owner think like an accountant

GST is calculated and shown, never asked for.

02

One source of truth

Counter, Shopify and purchases all write to the same stock number.

03

Show consequences, not just data

A sale does not only record revenue - it moves stock and books the cost.

04

Capture it when it happens

Expenses take a receipt photo at the moment of spending, not at month end.

05

Design around business questions

Navigation is grouped by what the shop is asking, not by database table.

06

Never guess an irreversible default

GST registration is asked, because it can be switched on but never off.

TL;DRThe interface hides the accounting so the shop never has to think like an accountant.

The money model

One sale, followed all the way to profit

This is the product’s whole argument. Click through a single sale and watch what it touches.

Step 1 of 7

Customer buys a saree

₹2,360 paid at the counter.

Invoice created

What “profit” actually means

Revenue minus everything - which is why the dashboard was designed last.

  • Revenue₹2,00,000
  • Cost of goods−₹1,20,000
  • Shipping−₹8,000
  • Ads−₹15,000
  • Rent−₹20,000
  • Salaries−₹18,000
  • Other−₹5,000
Real profit₹14,000

A billing app would have stopped at the first bar. The dashboard was designed last, on purpose - a profit number means nothing until every outflow is in.

GST, without asking the cashier

Same total either way. The split is derived, never chosen.

Saree
₹2,000
CGST 9%
₹180
SGST 9%
₹180
Total
₹2,360

The cashier never picks between these. The split is derived from the buyer’s GSTIN and the total is the same either way - but filing the wrong one is a filing error, not a display bug.

Input tax credit you can actually keep

A purchase bill is only claimable if the supplier really filed it.

  1. Purchase invoice
  2. GSTR-2B
  3. Match
  4. Eligibility
  5. Input tax credit

The bill appears in GSTR-2B, so the credit is safe to claim.

One stock number, three channels

The counter, Shopify and supplier bills all move the same figure.

  • Opening stock+1212
  • Counter saleInvoice-111
  • Supplier billPurchase+516
  • Shopify orderWebhook-115
On the shelf15
  1. Counter
  2. Shopify
  3. Purchases

One inventory model

Two stock counts drift, and the customer is the one who finds out. Every channel writes to the same number.

  1. Shopify order
  2. Filarity
  3. Stock updated
  4. Dashboard updated

An online order behaves exactly like a counter sale: stock moves, revenue lands, and the dashboard is already right.

Product decisions

Six decisions, and what each one cost

Product management on my own work meant deciding what the app refuses to do.

Should GST complexity be visible to the user?

Hide it. Show the result.

Trade-off
Considerably more logic behind the scenes.
User benefit
A cashier bills without thinking about tax at all.

Where should the dashboard stop?

Not at revenue. At real profit.

Trade-off
The dashboard could not ship until purchases and expenses existed.
User benefit
The number on the screen is the number the owner cares about.

How does someone evaluate this without signing up?

A public read-only demo of the real app.

Trade-off
A whole seeded dataset and a write-refusing session to maintain.
User benefit
No sign-up between curiosity and the actual product.

What should a Google sign-up assume?

Nothing irreversible. Ask instead.

Trade-off
One more question during onboarding.
User benefit
The shop is never committed to something permanent by default.

How much should entering a supplier bill demand?

Two modes: fully itemised, or file it with a photo.

Trade-off
Two paths to support instead of one.
User benefit
A rushed shop still captures the bill rather than skipping it.

What should staff be able to see?

Only the sections the owner switches on.

Trade-off
Per-section permissions to design and enforce.
User benefit
Staff can bill without seeing cost price or margin.

What shipped

GST invoicing

CGST/SGST/IGST split from the buyer’s GSTIN, HSN codes, live preview, A5 print, PDF export, one-tap WhatsApp delivery.

Stock that counts itself

Every sale and purchase bill moves stock. Barcode scanning at the counter, printable label sheets, low-stock views.

Purchases & supplier dues

Supplier bills bring stock in and create a payable. Two entry modes: fully itemised, or file the bill with a photo.

Expenses

Ads, rent, shipping and salaries with receipt photos - so profit is revenue minus everything, not revenue minus cost of goods.

GST & ITC

GSTR-1 export, GSTR-2B upload and reconciliation, per-purchase ITC eligibility, and a monthly sheet emailed to the accountant automatically.

Online orders

Shopify OAuth and webhooks pull orders in and push inventory back. A5 delivery slips, courier tracking, one pipeline for both channels.

Team & accountant access

Owner, staff with per-section permissions, and a read-only accountant login that can read the books and never write to them.

Admin & billing

A separate console for accounts, trials and subscriptions. The marketing site reads the plan price from a public feed, so a price change needs no redeploy.

Engineering

How the designed experience was made to work

The architecture exists to serve the product above it. Pick a piece to see what it does.

API routes

Around 77 endpoints. Every one sits behind a single authorisation gate rather than carrying its own permission check.

Access control, seen from both sides

Switch role and the interface changes. The server changes too - and it is the one that counts.

  • New invoice
  • Invoices
  • Stocks
  • Customers
  • Dashboard
  • Expenses
  • GST & ITC
  • Settings

Hiding a menu item is a courtesy, not a control. Every request also passes a single edge proxy that resolves the session and applies that role’s allow-list, so a write from an accountant or demo session is refused before any handler runs.

Two shops, one database

A customer must never see another customer’s books.

Shop A

  • Invoices
  • Customers
  • Stock
  • Expenses

Shop B

  • Invoices
  • Customers
  • Stock
  • Expenses
No query crosses

One customer must never see another’s books. Isolation is enforced on every query, and it is a rendering problem too - uploads are validated down to self-contained raster images, so one tenant cannot plant a tracking pixel that fires in another’s session.

Decisions worth defending

Shipping it

  1. Code→
  2. Migration→
  3. Verification→
  4. Production

Vercel for both sites, Neon for Postgres, an idempotent migration runner for schema changes, scheduled jobs for the monthly accountant report, and audit logging on anything that touches money.

TL;DREngineering here is in service of the experience - not the other way round.

Outcome

A real shop, running on it daily

Not a concept, and not a prototype. A working counter uses this to bill customers.

Before

Six places to look, and no single answer.

After

One system, one ledger, one profit number.

Result

Sales, stock, expenses, GST and profit in one place.

What I did on it

  • Product definition - what the app is for, and what it deliberately refuses to do
  • User research - built against one real shop’s daily workflow before generalising
  • UX and UI design - every screen, the design system, and the marketing site
  • Full-stack engineering - front end, API layer, database schema and queries
  • Domain modelling - GST, input tax credit, stock movement, subscriptions
  • Integrations - Shopify, transactional email, WhatsApp, courier tracking
  • Security - authentication, authorisation, tenant isolation, encryption at rest
  • DevOps and release - hosting, migrations, scheduled jobs, running the live app

See it yourself

There is a public read-only demo seeded with a fictional shop’s trading, so you can walk the real application - the dashboard, billing, stock, purchases, GST - without signing up for anything.