One catalogue
Enter an item once
The counter, the purchase bill, the label sheet and the online store read the same item, the same units and the same prices per unit.
CODENAME: RIVERFISH · PHASE 0 · BRAND TBD
Project River Fish is a suite of business apps for retail and trade shops — the counter, stock, purchasing, customer accounts, invoicing, tax, people, and the rest — every one of them writing to one append-only ledger that keeps working when the internet does not. The counter is ringing up real sales in a pilot shop today. The other apps are arriving on the same foundation, one at a time, and each says on this page exactly how far along it is.
0.00
Float drift — money is integer minor units
100%
Sales that complete offline
0
Conflicts when branches re-sync
2×
Native clients, one sync contract
The apps
Start with the counter. Add stock when you want to know what is on the shelf, purchasing when you want to know what it cost, khata when customers buy on account. Every app you add reads the same catalogue and writes the same ledger, so nothing is exported, re-keyed or reconciled between them.
1 in a pilot shop13 in build34 coming
A keyboard-first counter for a busy trade shop: scan, price by the pack, print, all with the network down.
Every customer’s account — what they owe, what they paid, and how old the balance is.
A return against the original bill, at the tax and discount it was actually sold at.
Quote a job, hold the prices, and turn it into a bill when the customer says yes.
Recurring bills for the customer who is supplied on a monthly account.
Hire out tools and equipment against a deposit, with returns tracked like stock.
Tax invoices that say what they are — and claim nothing the shop cannot back.
Input and output tax by rate, per period, from figures frozen on each line when it was posted.
A chart of accounts over a ledger that already never rewrites a posted row.
Rent, electricity, wages — recorded against the month they belong to, not the day they were paid.
Pivot the ledger without exporting it, and keep the figures live.
Supplier bills, warranties and photos, filed against the record they belong to.
Sign a quotation or a delivery note on the tablet and keep the signed copy with it.
Stock derived from movements, in base units, across every branch — never a column somebody can overwrite.
Supplier bills with freight and duty landed onto each item’s cost, at the pack size that supplier ships.
What is owed to whom, paid against which bill, and what is still open.
A label designer at true size, batch sheets, and one barcode per pack unit.
Cut, mix or assemble stock into a new item and cost it from the parts.
Inspect what arrives before it goes on the shelf, and record what was sent back.
Equipment, service dates, and who fixed what.
Who works where, with which role at which branch — and an audit trail of who changed it.
Shifts worked and leave taken, by branch.
Wages computed from attendance and paid out as an expense the ledger already knows about.
Openings, applicants, and the interview that decided it.
Reviews on a schedule, with the sales figures already to hand.
The delivery van: fuel, service, and which deliveries it made.
Receipts, reminders and statements sent where customers already are.
A balance reminder or a ready-for-collection message, from the ledger, not from a phone.
Points, bundles and seasonal prices that the counter applies without anyone remembering them.
A page for the shop — hours, location and the catalogue — in both languages.
Sell from the same catalogue and the same stock as the counter.
A monthly note to customers who asked for one.
A question on the shop’s page, answered from the counter.
Ask a customer how it went, once, after the bill.
Fitting and repair jobs out of the shop, billed from the same catalogue.
Job work for the contractor who buys from you — materials, labour, and what is left to bill.
Complaints and warranty claims, tracked to a resolution against the bill they came from.
A delivery slot or a site visit, booked against a calendar the shop can see.
Hours against a job, so labour is billed as carefully as materials.
Who is on which counter, which day.
Today across every branch, low stock, and the ops the server could not fold — on the server, in the shop’s own day.
Sales, purchases, profit and loss, ageing and tax — exported to Excel as numbers, not text.
Excel in, a full diff shown before anything is saved.
Ask the ledger a question in your own language; get a figure with its rows cited.
Messages between branches, attached to the bill they are about.
The shop’s own notes — how to price a cut length, whom to call for a part.
Scales, label printers and customer displays on the counter.
A call from a customer opens their account before you pick up.
“In pilot” means running on real sales in a real shop. “In build” means code and tests, no shop yet. “Coming” means a name and a sentence. This list is the plan, and more apps will be added to it as they are named.
The platform
The apps differ on the screen and agree underneath. Each one appends operations to the same log, reads the same catalogue and stock, and syncs through the same contract — so an app added next year does not need last year’s data moved into it.
01
Every movement of inventory or money appends an immutable row. On-hand stock is the sum of those movements — there is no mutable column to corrupt, so “−22.5 PAIR” can never happen silently again.
02
The counter completes sales with the network down. Operations queue in a local outbox and sync later — idempotent and commutative, so two branches re-joining after an outage converge with no conflict resolution at all.
03
A void is a reversing entry, not a delete. A corrected cost is an adjustment row, not an edit. History stays auditable because the only way to change it is to append to it — which is what makes a figure worth citing.
First fish · counter POS
Keyboard-first with the F-key map the staff already know, a scan field that never loses focus, and sync state always visible. Dense on purpose — matched to a twelve-hour shift, not a demo.
Total sales
Rs 77,850.45
▲ 12.4% vs last Saturday
Sale bills
68
Rs 1,144.86 average bill
Purchases
Rs 7,000.00
Rs 3,500.00 freight allocated
Counter dashboard · all-branches roll-up — the thing the legacy box cannot do
Total sales
Rs 77,850.45
▲ 12.4% vs last Saturday
Sale bills
68
Rs 1,144.86 average bill
Purchases
Rs 7,000.00
Rs 3,500.00 freight allocated
Tablet 1194×834 · the same ledger, on the floor
Total sales
Rs 77,850.45
▲ 12.4% vs last Saturday
Sale bills
68
Rs 1,144.86 average bill
Purchases
Rs 7,000.00
Rs 3,500.00 freight allocated
Owner's phone · installable PWA · the same ledger, from anywhere
For developers
Every mutation is an operation in an append-only log, keyed by a client-generated ULID — replay it twice, it applies once. Device identity is a first-class credential: pairing, seat metering, remote revoke.
The same /v1 and /sync contract drives the web PWA, the Kotlin Android client, and whatever ships next — held together by shared conformance fixtures, not shared code.
POST /v1/sync
{
"deviceId": "dev_01J9K3…",
"ops": [ {
"opId": "01JD8FZK7Q…", // ULID — the idempotency key
"type": "sale.create",
"branchId": "br_ravi_road",
"clientSeq": 4182,
"payload": { "totalPaisa": 7785045, "lines": […] }
} ]
}→ 200 { "applied": 1, "duplicates": 0, "cursor": "…" }
Native AI
An AI that reads your shop is only worth having if you can check it. Most cannot be checked: they answer from a database of mutable cells, where last month’s figure has already been overwritten by this month’s correction and nothing records that it happened.
Because River Fish never rewrites a posted row, every figure has a provenance — the exact movements it was summed from, and the operations that created them. An answer arrives with that range attached, so checking it is reading a report, not taking a guess on trust.
Ask in Urdu or English, typed or spoken, from any counter or the owner’s phone. The answer carries the movement range behind it — tap it and you are looking at the rows themselves.
کل راوی روڈ کی نیٹ سیل کتنی تھی؟
Rs 44,150.00
grounded → stock_movements 18,204–18,412
Which glue lines have not moved in 60 days?
Rs 92,400
grounded → 0 movements against 14 item ids
Ask the counter — sales, prices, stock, in your language.
Reorder suggestions, slow movers, stock reconciliation.
Overdue-balance nudges and drafted reminder messages.
Plain-language questions become date-ranged, cited reports.
Describe a label, get a print-ready template.
One platform
A shop that runs on five tools re-keys the same item five times and reconciles the differences at month end. Here there is one catalogue, one customer list, one stock figure and one ledger, and every app is a different screen onto them.
One catalogue
The counter, the purchase bill, the label sheet and the online store read the same item, the same units and the same prices per unit.
One ledger
A sale, a purchase, a return and a stock count are all rows in one append-only log. There are no two systems to disagree.
One sign-in
One account, one role at each branch, one audit trail — the same across every app, set in one place.
Add when needed
Every app is there from the first day and switched on when the shop wants it. Nothing is migrated in later.
Built for every counter
Multi-branch
Branch-level tills and stock with an all-branches roll-up. Role per user, per branch.
Tax
GST, VAT or sales tax — codes on documents, input and output reports, landed cost that knows whether you are registered.
Languages
UI, master data and printed bills in your language — LTR and RTL alike; per-user screen language, per-tenant print language.
Units
Multi-unit items, per-supplier pack sizes, weight goods with nominal piece factors. Prices are stored per unit, never multiplied out.
Barcodes
WYSIWYG label designer at true scale, batch sheets, a barcode per pack unit.
Import
Excel import with column mapping and a reviewable diff before anything commits.
Pricing
River Fish is being built inside a real, working shop — the pilot sets the bar for speed, density and correctness before a single subscription is sold, and the number lands with the public release. The shape of it is already decided.
Phase notes, app launches, and the eventual name — straight from the riverbed.
Build notes only. No sales mail, and you can leave in one click.