Skip to content
Farhad Nazir

Optical retail POS and prescription system

Drivoli Optics Software

A multi-branch Windows desktop system for an optical retailer, covering prescriptions, stock, counter sales, repairs and supplier ledgers.

Role
Sole developer
Platforms
Desktop (Windows), Backend & API
Status
Delivered to client
Timeline
2025 – 2026
  • Desktop app
  • Business system
  • SaaS product
Drivoli Optics sales console with filters, total revenue, expenses and net cash in hand cards, and a table of prescription, product, repair and expense entries with receipt, WhatsApp, download and delete actionsRecreated from source, demo data

Overview

Drivoli Optics Software is a Windows desktop application for a multi-branch optical retailer. It brings patient prescriptions, frame, lens and contact-lens inventory, counter sales, repair jobs and supplier ledgers into one system designed to be shared across branches, while keeping each branch's data separate.

It is a white-label build of Asaan Optics, my own desktop product for optical shops. Instead of starting again, I rebranded the existing codebase and extended it with what a multi-branch business needs: owner, branch and staff accounts, a View-As mode that lets the owner open any branch, and per-staff module permissions.

The Flutter desktop client talks to a Node.js and Express REST API backed by a cloud MySQL database. I packaged it as a versioned Windows installer and handed it over with formal technical documentation, which the client approved.

Built for: Owners, branch managers, optometrists and counter staff working across the branches of an optical retail business.

The problem

A multi-branch optical business has to manage prescriptions, frame, lens and contact-lens stock, counter sales, repairs and supplier balances in several branches at once. Each branch needs to see only its own records, while the owner needs to move between branches without logging in and out.

The day-to-day details matter too. Staff should only see the modules relevant to their job, receipts must print cleanly on low-cost 57mm and 80mm thermal printers, and a dropped internet connection should not lose a sale or a prescription that was just entered.

The solution

I built on the Asaan Optics desktop codebase, whose data layer I had already moved from Firebase to a central Node.js and Express API on a MySQL-compatible database, with every record scoped to a shop by its user ID. A client-side scope manager decides which shop's data to load based on the account type: branches see their own data, staff see their parent shop, and owners pick a branch to view.

Staff accounts carry a permission matrix that hides modules such as the dashboard, POS or stock control from the side menu. Writes made while the connection is down go into a persisted queue and are sent automatically when it returns. A PDF engine renders prescription, sale and repair receipts in four thermal roll sizes plus A4 and A5, with margins tuned per format so nothing clips at the edge.

Main features

What the software does day to day, taken from the code.
  • Patient prescription records

    Customer profiles with right (OD) and left (OS) eye cards, an IPD card, frame and lens selection, referring doctor, discount, advance and balance. Each record prints as a receipt for the customer.

  • Frame, lens and contact-lens inventory

    Stock control for frames, lenses, contact lenses and general products, with stock adjustments. Lenses are tracked by type and coating, and contact lenses by expiry date.

  • Barcode generation and scanning

    The app generates barcodes for stock items and finds products by scanned barcode, with debounced search and an audio beep to confirm each scan at the counter.

  • Thermal and paper receipts

    Prescription, sale and repair receipts print in 57x50, 57x70, 80x70 and 80x80mm roll formats or on A4 and A5, and sales statements export as PDF.

  • POS sales and repairs desk

    A sales record with stats cards and server-issued serial numbers, plus a separate repair job workflow with its own numbering and printable receipts.

  • Owner, branch and staff roles

    Owners can view any branch through View-As mode, branches see only their own records, and staff work inside their parent shop with a per-module permission matrix.

  • Vendor ledgers

    Supplier records with a ledger of entries for each vendor, so outstanding balances are kept alongside stock.

  • Dashboard, analytics and export

    Dashboard charts, a product performance report and stock analytics, with customer and sales data exportable to Excel or CSV.

  • Optical vision tools

    Built-in calculators for prescription transposition, vertex distance and reading add for both eyes, so staff do not need a separate reference.

  • Local payment and currency settings

    Sales record payment methods including cash, bank transfer, EasyPaisa and JazzCash, with configurable currency and country code. Customers can be messaged on WhatsApp in one click.

Screens marked "recreated from source" were rebuilt from the app's code with demo data, so no client data is shown. The rest are from the software itself.

Drivoli Optics prescription form with customer details, right and left eye SPH, CYL, axis, VA and ADD, pupillary distance, frame and lens selection from stock, and lab outsourcingRecreated from source, demo data
Prescription entry covering both eyes, ADD and IPD, frame and lens selection from stock, and lab outsourcing.
Drivoli Optics point of sale for a staff account: customer fields, order items with quantity and price, barcode search row, remarks, grand total and Finalize Sale buttonRecreated from source, demo data
The counter POS for staff, where products and contact lenses are added by search or barcode scan.
Drivoli Optics stock control center in owner monitoring mode for one branch, with stock value, expected revenue, projected profit, low stock alerts and inventory management cardsRecreated from source, demo data
Stock control, seen by the owner through View-As monitoring of one branch.
Drivoli Optics frame inventory table with brand, model, colour, size, frame type, price, stock with low-stock warnings and per-row actions including barcode and stock top-upRecreated from source, demo data
Frame inventory, with low-stock flags, barcode generation and stock top-ups on every row.

Development and architecture

The system is client-server. A Flutter Windows desktop client (around 150 Dart files) uses BLoC and Provider for state and calls the API over HTTPS. The backend is a Node.js and Express 5 REST API that reads and writes a MySQL-compatible cloud database (TiDB Cloud) through a connection pool, and is hosted on Render.

The API covers users and branch linking, inventory with stock adjustment, prescriptions, sales with stats, repairs, serial number counters, device registration and vendor ledgers. Data is partitioned per shop by user ID, and the desktop client decides which scope to request for the signed-in account.

The desktop app is distributed as a Windows installer. A PowerShell script builds the release, writes the version number and compiles an Inno Setup package. Four versioned installer releases were built during delivery.

White-label fork instead of a rebuild
I reused my Asaan Optics desktop product and rebranded it for Drivoli (package name, assets, installer), then added the multi-branch features on top, keeping the existing modules instead of rewriting them.
Firebase to Node.js and MySQL
The product moved from Firebase and Firestore to its own Express API on MySQL. I wrote a migration script with date normalization and batched inserts, and added a password setup flow for accounts carried over without a password.
Scope manager for branch isolation
A client-side scope manager resolves the data scope from the account type, parent shop and the owner's View-As selection. Owners see empty tables until they choose a branch, so branch data is never mixed by default.
Offline write queue
POST and PUT requests made offline, or while the server is unreachable, are stored in a persisted queue and replayed on reconnect. A lock prevents the queue from being processed twice.
TiDB compatibility work
Moving to TiDB Cloud meant replacing SQL_CALC_FOUND_ROWS with separate COUNT queries and paginating prescription and repair customers together with UNION ALL.
Hashed password login
Email and password sign-in checks bcrypt hashes on the server, and accounts migrated without a password are taken through a password setup step. Session details such as account type and staff permissions are cached locally to drive the interface.
Reproducible Windows installer
The Inno Setup installer bundles the release build, installs the Visual C++ runtime only when a registry check shows it is missing, and offers a desktop shortcut.

Technology

  • Flutter
  • Dart
  • Node.js
  • Express.js
  • MySQL
  • TiDB Cloud
  • BLoC
  • Render
  • Inno Setup
  • PowerShell
Asaan Optics Desktop Stock Control Center showing stock value at cost and retail, potential profit, stock by category, last 30 days of sales and low-stock alerts

Optical shop management SaaS

Asaan Optics

Optical shop software for Android and Windows: prescriptions, counter sales, stock and staff shifts on one shared shop account.

  • SaaS product
  • Mobile app
  • Desktop app
  • Business system
Tabarak POS billing screen with a menu grid of dishes, a dine-in order for Table 1, discount and tax fields, tendered amount and change return

Offline restaurant POS

Tabarak POS

An offline-first restaurant point of sale for tablets and Windows PCs, with billing, kitchen tickets, tables, reports and thermal receipts.

  • Desktop app
  • Mobile app
  • Business system
Asaan Jewellers POS dashboard showing per-gram rates for 999 silver and 24k, 22k and 21k gold, today's sales, stock weight, receivables, gold pending with karigars and recent invoices
In development

Jewelry shop POS and ledger

Asaan Jewellers POS

An offline Windows POS and ledger for gold jewelers, with daily metal rates, old-gold exchange, customer credit and artisan tracking.

  • Desktop app
  • Business system

Have a software idea or a business process that needs a proper system?

Tell me what you are trying to fix. I will reply with honest questions, a practical plan and a realistic estimate.