---
title: "MedVoice"
description: "A voice-assisted order and billing workflow for pharmaceutical wholesalers, where speech proposes a line and deterministic rules decide identity, tax, and posting."
canonical: "https://www.ayushrai.site/products/medvoice/"
last-updated: "2026-10-11"
---

# MedVoice

Source: https://www.ayushrai.site/products/medvoice/
Markdown: https://www.ayushrai.site/products/medvoice.md

A voice-assisted order and billing workflow for pharmaceutical wholesalers, where speech proposes a line and deterministic rules decide identity, tax, and posting.

Stage: Building. Phase 2 foundations are in the repository, including a mock path from speech to a confirmed draft invoice. Real catalog import, production speech, the Android field app, inventory hardening, and live ERP sync are not complete. There is no public demo URL.
Category: Enterprise workflow.

## Thesis

A warehouse worker should be able to speak an order line and still produce an auditable wholesale invoice, without letting a model guess the medicine, the price, or the tax.

## Audience

- Floor workers at pharmaceutical wholesalers and stockists
- Owners, accountants, and managers who have to trust the invoice

## Problem

Pharmaceutical wholesalers bill through a handoff from the person picking stock to the person typing the invoice. Look-alike medicines, pack sizes, and tax make that handoff a high-consequence transaction.

## Approach

Use speech as one input into a constrained workflow. The model must not decide medicine identity, price, quantity, or tax. Ambiguous matches require confirmation. Invoice posting is idempotent, and an ERP failure is not a success.

Today the worker picks, then tells an accountant, who types the bill. That serial handoff creates the wrong medicine, the wrong pack, and a bill that does not match the shelf.

1. A worker speaks an order line.
2. Speech is normalized and matched only against that tenant's medicine catalog.
3. Ambiguous or risky matches stay unconfirmed until a person accepts them.
4. The system builds an auditable draft order.
5. Tax is computed with deterministic GST logic, in integer money, not by a model.
6. Invoice posting and ERP sync follow explicit confirmation and idempotent rules. An ERP failure is not reported as a successful sale.

## Architecture

- Frontend: Next.js admin for owners and accountants. Android worker app in Kotlin and Jetpack Compose, still a scaffold that needs a device toolchain.
- Backend: NestJS modular monolith. Domain rules cover matching, order state, confirmation, and invoice idempotency.
- Data: PostgreSQL is the intended source of truth, with Redis prepared beside it. The API still defaults to an in-memory demo catalog. Money is stored in paise.
- Speech providers sit behind an adapter. Mock speech is the default. A Deepgram adapter exists and does not run without a key.
- ERP adapters implemented: mock and CSV. Marg, Busy, and Tally are specified, not live.
- Provisional stack (Set A) until the architecture choice is locked.

## Implemented

- Medicine master model, alias-aware matching, and a voice path that creates unconfirmed draft lines.
- Order state machine, explicit confirm and reject, deterministic GST on the voice-to-invoice path, and in-memory idempotent invoicing.
- Admin shell for catalog search, orders, voice-session debug without raw audio, and audit events.
- Mock and CSV ERP adapters.

## Experimental

- Streaming speech and the Android push-to-talk path. Both exist as code and still depend on credentials or hardware.
- Multi-tenant isolation and roles are started, not a finished authorization suite.
- Docker Compose prepares Postgres and Redis. Durable database wiring is partial.

## Planned

- Real warehouse catalog import, stock reservation, invoice PDF, live ERP sync, dealer portal, and a production rollout.
- Manual prerequisites still open: a real catalog export, speech credentials, Android devices, a legal stance on audio retention, and an ERP sandbox.

## Open questions

- Which speech provider is accurate enough on a warehouse floor to leave the mock adapter?
- When does Postgres replace the in-memory catalog as the system of record?
- The stack choice is still provisional. What has to be reworked if it changes?

## Trade-offs

- Mock speech and a demo catalog make the founding loop runnable locally, and they say nothing about a noisy warehouse.
- Refusing silent matches slows the picker down on purpose. A wrong strength or pack is more expensive than an extra confirmation.
- Coexisting with Marg, Busy, or Tally is slower than pretending to replace them.

Source repository: https://github.com/ayushrai-hub/MedVoiceERP
Case study: /work/medvoice

_Unverified award metrics are omitted. Wording matches the public site._
