Skip to content
SNOWBROS

The retail system a working boutique runs its counter on

A keyboard-first till, invoicing, inventory, customers and trade reports for Vinny's Fashion Hub. One Next.js codebase, shipped to the web and as an offline-capable Windows desktop app.

Vinny's Atelier till: a draft invoice with three line items, a discount, and Razorpay selected as the payment method.
  • Command palette. Every action on the till has a key. Search, customers, new invoice and print are all one shortcut away.

  • Draft numbering. An offline till numbers its own invoices from a per-device shard, and sync keeps that number.

  • Thermal printer. Receipts print straight from the till; the same document model renders the PDF.

  • One discount module. The server, the offline till and this panel call the same function. The result is frozen onto the bill.

  • Integer paise. Every amount is an integer number of paise from input to PDF. No float touches a rupee.

  • Dynamic UPI QR. Razorpay generates a QR for the exact amount. The invoice is written once the payment is confirmed.

The problem

The shop ran on a paper book and a phone camera. Invoices were hand-written and unnumbered, stock was whatever the shelf looked like, and a return weeks later had nothing to trace back to. Off-the-shelf POS software assumed a chain, a barcode gun and a monthly fee.

What we built

A single application shaped around the counter's real workflow. The till is the home screen: a draft invoice that pulls garments from the catalogue on a keystroke, applies discounts, settles against cash, UPI or a Razorpay dynamic QR, and prints to the thermal printer. Behind it sit inventory with a stock-movement ledger, customer records by lifetime spend, and reports net of discounts.

Decisions, and why

  • The desktop app is a window, not a second application

    Tauri wraps the live deployment. Bundling the server would have shipped the database service key and the Razorpay secrets to a counter PC. A window keeps every secret on the server and one deployment as the source of truth.

  • An offline till numbers its own invoices

    Sales settled without a network are numbered from the device's own shard, and sync adopts that number. The receipt in the customer's bag is never renumbered, and a retried push finds its invoice instead of creating a second one.

  • Money is an integer

    Every amount is held in paise from input to PDF. No floating-point value ever touches a rupee figure.

  • Discount rules live in one module

    The server, the offline till and the summary panel all call the same function, and the result is frozen onto the bill, so editing a rule later cannot rewrite an old invoice.

Scope

  • Keyboard-first till: catalogue, quantity and discount without leaving the keys
  • Razorpay dynamic UPI QR, cash and UPI settlement
  • Invoices as PDF and as thermal receipts from one document model
  • Offline sales with a local SQLite store, outbox and conflict states
  • Inventory by variant with a stock-movement ledger
  • Invoice delivery over WhatsApp, configurable per shop
  • Row-level security and an operator allowlist; no public sign-up

Built with Next.js 16, React 19, TypeScript, PostgreSQL, Supabase, Drizzle ORM, Tauri 2, SQLite, Razorpay, Playwright

Release history

Vinny's Atelier, recent releases
RevChange
1.5.0Offline invoice identity, quantity discount bands, invoice delivery over WhatsApp
1.4.2Closed XSS, sync-trust and header gaps before release
1.4.1Desktop hands the Razorpay payment page to the browser
1.3.0Fractional discounts, keyboard fixes, dynamic UPI QR on desktop

Next sheet

Accounic

A multi-currency ledger where the database computes every balance