New
Apps 742Makers 742This week 742
Promote your app−30%
1views in
the last 30 days

AwaazOS Bol. Bill. Becho.

AI Voice-Powered Billing & UPI Payment Platform for Indian Vendors — Bol. Bill. Becho.

Built with Claude/Claude Code

by gengirish · from INIndia · added Oct 29, 2026
no ratings0 comments

AwaazOS — Bol. Bill. Becho.

Orders, UPI billing and receipts for India's home kitchens that sell on Instagram and WhatsApp. Post a batch with a cut-off or an everyday menu → buyers order from your link in bio or on WhatsApp → paid by UPI → cook list and delivery list on the day → receipt on WhatsApp. Voice POS for counter sales. 30 days free.

Status: Production-deployed, with design-partner vendors in Hyderabad. Live counts are on the admin-only /admin/metrics page.


🎬 60-Second Demo

Voice command in Hindi → cart fills in real time → UPI QR → WhatsApp receipt. Sixty seconds, end-to-end, on a real phone, in a real chai stall.

The recorded video is not published yet. The original April 2026 script is archived (and partly stale) at docs/archive/DEMO_VIDEO.md.

Live walkthroughs (Zoom / investor rooms): docs/DEMO_GUIDE.md.


🌐 Live demo

Surface URL
Production app https://awaazos.vercel.app
Pricing https://awaazos.vercel.app/pricing
Sign up https://awaazos.vercel.app/sign-up
GitHub https://github.com/gengirish/awaazos
60s video demo not published yet
Live demo script docs/DEMO_GUIDE.md (Zoom / investors)

60-second test: sign up → onboard a stall → add 3 menu items → open /pos on your phone → tap the orange mic → say "do samosa aur ek chai" → see the cart fill → scan the UPI QR → bill AWZ-YYYYMMDD-0001 is generated atomically → check /analytics.


🎯 Who it's for

Instagram-based cloud kitchens: home bakers, meal-box kitchens, snack and sweet makers who find buyers on Instagram and sell direct, not through Swiggy or Zomato. Today their orders live in DMs, payments are UPI screenshots, and the cook list is a notebook. Full profile, fit and gaps: docs/ICP.md.

What they use: the storefront /s/[slug] as their link in bio, Drops (a batch with a cut-off and capped stock), UPI / pay-on-delivery / their own Razorpay, the orders board and prep sheet, Web Push alerts, and a ready-made Instagram story image for each drop.

The sections below describe the original counter-POS wedge (street stalls and kiranas). That product still ships and still works; it is no longer who we build for first.

🌶️ The problem (original counter-POS wedge)

India has 63 million MSMEs and ~25 million micro-merchants — chai walas, dosa carts, kirana shops, samosa stalls, paan shops. They:

  • Take orders verbally in Hindi / Telugu / Kannada / Tamil / Marathi / Bengali (rarely in English)
  • Hand-write bills on paper or skip billing entirely (lose 15-20% of revenue to inventory leakage and disputes)
  • Accept UPI but can't tie payments to orders
  • Have no idea which item sold most, what their busiest hour is, or how much they actually made today
  • Can't afford ₹2,000-5,000/mo POS systems built for English-speaking, literate restaurant managers

The gap: existing POS software (Petpooja, Zomato Hub, Square clones) assumes a manager-class user who can type, navigate menus, and trust an English UI. That cuts out 90% of India's actual point-of-sale.

💡 The solution

A POS where the only interface is your voice and your eyes.

  1. Vendor speaks the order in Hindi or English → the browser's Web Speech API transcribes it (a server-side STT cascade exists as an opt-in fallback; see Tech stack below)
  2. Claude Haiku 4.5 parses the transcript against this vendor's exact menu (with prompt caching) and emits structured items via tool-use
  3. Cart fills, total computes in paise (no float math, ever)
  4. Vendor taps Collect Payment → big UPI QR code → customer scans with GPay / PhonePe / Paytm
  5. Mark as paid → atomic bill number AWZ-20260423-0001 → DB transaction commits → vendor taps Send on WhatsApp and the receipt opens pre-filled in their own WhatsApp (wa.me link)
  6. Owner sees real-time dashboards (revenue trend, top sellers, hourly heatmap, voice adoption %)

All of this on a phone, in <8 seconds per transaction. Hindi + English at MVP. More on roadmap once 50 vendors are active.


✨ Features

Built and shipped

  • 🎙️ Voice-first POS — 80×80 mic button, 6 visual states (idle / listening / transcribing / parsing / success / error), distinguishable beyond color, full aria-live for screen readers
  • 🌍 STT routing — Web Speech in the browser for English & Hindi. A server cascade (/api/ai/transcribe, STARTER+) is wired with per-provider circuit breakers: OpenAI → Groq → self-hosted Whisper for en/hi, Sarvam Saaras v3 → Groq → Whisper for Telugu / Kannada / Tamil. te/kn/ta are dormant: the code and golden fixtures are kept, but the language picker offers only English and Hindi
  • 🧠 Two-tier AI parsing — Claude Haiku 4.5 primary with ephemeral prompt caching on the menu, escalates to Sonnet 4.5 on empty or low-confidence results (shouldEscalate()) or a Haiku error
  • 💰 Integer-paise math everywhere — no parseFloat, no toFixed (single exception: UPI deep-link am= per spec)
  • 🔢 Atomic bill numbering — AWZ-YYYYMMDD-NNNN via BillSequence.upsert inside prisma.$transaction, race-safe across concurrent sales
  • 📲 WhatsApp receipts — the vendor sends the bill from their own WhatsApp via a pre-filled wa.me link (GET /api/receipts/message); no Business API, no template, free on every plan. Customer phone is PII-protected (never logged, only last-4 in CSV exports). An older Gupshup + BullMQ path is still in the code but unused by the UI
  • 💳 UPI deep links + QR — vendor's own UPI ID, no MDR fees, scannable from any UPI app
  • 📊 Analytics dashboard — Recharts revenue trend, hourly heatmap, top sellers, voice adoption %, payment method breakdown — every chart has a <details> data table for accessibility
  • 🏢 Multi-tenant — vendorId scoping enforced on every query, two-layer RBAC (platform UserRole + per-tenant StaffRole)
  • 💸 Trial + Razorpay subscriptions — 30-day free trial with Starter limits, then Starter at ₹299/month or ₹2,990/year (+ GST), paid in place with Razorpay Checkout. Trial, paid and locked states are derived on every read (billingAccess()), with no timers; a locked store keeps read access to its records. A super admin can extend a store's free access by date (/admin/vendors)
  • 🖼️ Store banner & logo — the owner uploads a cover photo and logo for /s/[slug] in Settings → Online store; photos are shrunk on the phone before upload
  • 🛍️ Public storefront + Drops — opt-in /s/[slug] page where buyers order from the everyday menu or from a pre-order "drop" (cut-off, capped stock, prep sheet). Payment by UPI + the buyer's "I've paid" claim (the seller confirms), pay on delivery, or the vendor's own Razorpay keys. Optional Instagram and WhatsApp links in the store header
  • 📋 One orders board — /orders holds menu orders and every drop's orders, with a source picker, search, pickup/delivery filter, bulk confirm / mark paid / deliver, and Undo after handover
  • 🏷️ Offers — quantity plan discounts ("4+ quiches incl. 1 paneer → 10% off") on the storefront, drops and POS; one offer per order, priced by the server (lib/offers.ts, Settings → Offers)
  • 🗣️ Voice drop and menu builders — say a batch plan or a dish list; Claude drafts the drop form or new menu rows for the seller to confirm (/api/ai/parse-drop, /api/ai/parse-menu)
  • 🧾 Receipts — one receipt layout rendered as WhatsApp text, a printable 58 mm / 80 mm / A4 page with optional auto-print, and a public customer page /r/[token]; GSTIN printed when set
  • 📴 Offline counter sales — the POS keeps selling without a connection: sales queue in IndexedDB and sync when the phone is back online, never billed twice (clientRef)
  • 📸 Instagram story image — one tap on a drop makes a 1080×1920 PNG (items, prices, cut-off, order link) inside Instagram's safe zones, and copies the storefront link for the Link sticker (GET /api/drops/[id]/story-image)
  • 🔔 Web Push alerts — new storefront orders and payment claims push to the vendor's opted-in devices (lib/push.ts, public/sw.js); an open app also says "New order received from
  • ✅ Setup checklist — the steps to start taking orders follow the seller to /orders, /drops and /pos; in-app guide at /help
  • 🇮🇳 India-first defaults — IST timezone, DD/MM/YYYY dates, +91 10-digit phone validation, Intl.NumberFormat('en-IN', { currency: 'INR' }), libphonenumber-js
  • 🔐 Auth.js v5 (NextAuth) — Edge-split config, JWT sessions, Credentials provider with bcrypt, single prisma.$transaction for sign-up
  • 🎨 Mobile-first UI — Tailwind + shadcn/ui, saffron AwaazOS palette (primary tokens at 4.5:1 with white text), Baloo 2 headings + Nunito body, shared EmptyState / Notice / ResponsiveDialog primitives

Roadmap

Driven by docs/ICP.md "Plan, in order": validate with 5–10 kitchens running real drops, checkout inside Instagram's in-app browser, measuring Instagram demand, a store-level story image, and delivery hand-off from the prep sheet.

Also planned, not shipped: automated accessibility audits in CI (@axe-core/playwright is not installed today — a11y is hand-checked against the aria-live, contrast, and chart-data-table work listed above).


🏗️ Tech stack

Layer Choice Why
Frontend Next.js 15 App Router + React 19 + TypeScript strict RSC for server-side data fetch, no waterfall to API
UI Tailwind CSS 4 + shadcn/ui (slate) Fast iteration, accessible primitives, mobile-first
Charts Recharts ^2.15 SSR-friendly, accessible (data tables sibling)
Auth Auth.js v5 (NextAuth) + @auth/prisma-adapter + bcryptjs No vendor lock-in, edge-safe middleware, JWT sessions
Database Neon Serverless PostgreSQL Branchable, scales to zero, Indian-region availability
ORM Prisma Type-safe, $transaction for atomicity, upsert for idempotency
AI / Voice Anthropic Claude Haiku 4.5 (primary) + Sonnet 4.5 (fallback), tool-use, prompt caching Best Indic instruction-following at lowest cost
STT Web Speech API (en/hi, in-browser) + server cascade: OpenAI gpt-4o-mini-transcribe, Groq whisper-large-v3-turbo, Sarvam Saaras v3 (dormant te/kn/ta), self-hosted Whisper on Fly Web Speech is free and needs no server call from us; the cascade covers the opt-in server path, each hop behind its own circuit breaker
Background jobs BullMQ + Redis (Fly.io workers) Voice telemetry, retention runs, retries with backoff
Serverless KV @upstash/redis HTTP on Vercel Rate limits, idempotency keys, AI usage caps; no TCP from serverless
Payments Razorpay subscriptions (platform) · UPI deep link + QR (POS) · vendor's own Razorpay keys (storefront) India-first; storefront money goes to the vendor, never through the platform
Messaging wa.me links from the vendor's own WhatsApp · Web Push (web-push, VAPID) · AgentMail (password-reset and buyer magic-link email) No WhatsApp Business API or templates needed
Hosting Vercel (Next.js) + Fly.io BOM region (workers) Edge for users, BOM for low-latency to Indian compute
Storage Vercel Blob Menu item photos, store banner and logo
Testing Vitest (unit) + Playwright (E2E — chromium + Pixel 7 mobile, en-IN locale, Asia/Kolkata timezone) Fast unit feedback, real-browser E2E on the exact locale and timezone vendors run in

🚀 Quickstart (local dev)

# 1. Clone + install
git clone https://github.com/gengirish/awaazos.git
cd awaazos
npm install

# 2. Copy env template, fill in your secrets
cp .env.local.example .env.local
# Required to boot: DATABASE_URL, AUTH_SECRET (set AUTH_URL too)
# Required for voice parsing: ANTHROPIC_API_KEY
# Optional server STT: OPENAI_API_KEY, GROQ_API_KEY, WHISPER_STT_URL + WHISPER_STT_SECRET
#   (SARVAM_API_KEY only matters for the dormant te/kn/ta path)
# Optional: RAZORPAY_* (incl. RAZORPAY_PLAN_STARTER_MONTHLY / _YEARLY), BLOB_READ_WRITE_TOKEN,
#   VAPID keys (Web Push), AGENTMAIL_*, SENTRY_*
# Redis: UPSTASH_REDIS_REST_* (HTTP) and REDIS_URL (TCP, BullMQ) — see "Two Redis surfaces" in CLAUDE.md
# Every variable is documented in .env.local.example

# 3. Push Prisma schema to your Neon DB (no migration files, no seed script)
npx prisma db push

# 4. Run dev server
npm run dev
# → http://localhost:3000

# 5. (Optional) Run BullMQ workers locally (voice telemetry, retention)
docker run -d --name awaazos-redis -p 6379:6379 redis:7-alpine
npm run worker  # or: npx tsx workers/index.ts

Provision a Neon database

  1. Sign up at https://neon.tech
  2. Create project awaazos-db in the aws-us-east-1 region (closest to where Vercel deploys serverless functions; switch if Vercel deploys to Mumbai)
  3. Copy the pooled connection string → DATABASE_URL
  4. Copy the direct connection string (same URL minus -pooler from the host) → DIRECT_URL

Provision Anthropic

  1. Sign up at https://console.anthropic.com
  2. Create an API key, paste into ANTHROPIC_API_KEY
  3. Default models are claude-haiku-4-5 (primary) and claude-sonnet-4-5 (fallback) — override with ANTHROPIC_PRIMARY_MODEL / ANTHROPIC_FALLBACK_MODEL if needed

🧪 Quality & testing

npm run typecheck   # tsc --noEmit
npm run lint        # eslint . (ESLint 9 flat config)
npm test            # vitest run
npm run build       # next build
npm run e2e         # playwright (uses dev server) — chromium + mobile

Vitest unit + Playwright E2E (chromium + Pixel 7 mobile, en-IN locale, IST timezone). See ARCHITECTURE.md for the full testing stack and what each suite guards.

The E2E suite writes real rows (it registers vendors and rings up sales). Never run it against the production database or deployment; use a throwaway Postgres as shown in CLAUDE.md.


☁️ Production deployment

The app is deployed across these services:

Service Host What runs there
Web Vercel (awaazos.vercel.app) Next.js App Router, all /api/* routes, marketing + vendor pages
Workers Fly.io awaazos-workers (BOM region) BullMQ workers for voice-parse-log, send-receipt (dormant Gupshup path) and retention. The Fly app does not currently exist; see TODO.md 1.1
Whisper STT Fly.io (services/whisper-stt) Optional self-hosted last-resort ASR
Redis (HTTP) Upstash REST (UPSTASH_REDIS_* on Vercel) Rate limiting, idempotency, circuit breakers, monthly AI caps, /api/ready Redis probe
Redis (TCP) REDIS_URL, a public rediss:// endpoint BullMQ: Vercel routes enqueue, Fly workers consume
Database Neon Serverless Postgres (us-east-1) All app data, prisma.$transaction boundaries

The two Redis surfaces are not interchangeable; the canonical explanation is in CLAUDE.md.

Deploy from scratch

Vercel deploys through its GitHub integration. vercel.json skips every non-production build, so preview deployments are off and a push to main is a production deploy.

# 1. Vercel (frontend + API): connect the GitHub repo in the Vercel dashboard, then set env
vercel link
vercel env add DATABASE_URL production    # paste Neon pooled URL
vercel env add AUTH_SECRET production     # openssl rand -base64 32
vercel env add AUTH_TRUST_HOST production # value: true
vercel env add AUTH_URL production        # the public production origin
vercel env add ANTHROPIC_API_KEY production
# Upstash REST (Vercel serverless — rate limits, idempotency, /api/ready)
vercel env add UPSTASH_REDIS_REST_URL production   # https://....upstash.io
vercel env add UPSTASH_REDIS_REST_TOKEN production
# REDIS_URL: public TCP endpoint. Without it, BullMQ enqueues fail (voice telemetry is dropped).
vercel env add REDIS_URL production
# ... (add OPENAI_* / GROQ_* / WHISPER_*, RAZORPAY_*, VAPID keys, AGENTMAIL_*, BLOB_READ_WRITE_TOKEN, SENTRY_* as needed)
git push origin main   # builds and deploys production

# 2. Fly.io workers
flyctl launch --name awaazos-workers --region bom --no-deploy
# Provision Redis with a TCP URL workers can hold open (Fly Redis, or Upstash rediss://)
flyctl redis create --name awaazos-redis --org personal --region bom \
  --no-replicas --enable-eviction --enable-prodpack=false
# copy the printed URL — private Fly *.internal URLs do NOT work from Vercel
# A worker holds a TCP connection 24/7; on a pay-per-command Redis plan that bills even at zero traffic.

# DATABASE_URL + AUTH_SECRET are boot-required by lib/env.ts. GUPSHUP_* only feed the dormant
# receipt worker; the workers never call Anthropic.
flyctl secrets set --app awaazos-workers \
  REDIS_URL="rediss://..." \
  DATABASE_URL="postgresql://..." \
  AUTH_SECRET="..." \
  GUPSHUP_API_KEY="..." \
  GUPSHUP_APP_NAME="..." \
  GUPSHUP_SOURCE_NUMBER="..."

flyctl deploy --app awaazos-workers --remote-only --ha=false

The optional Whisper ASR service has its own Fly app and instructions in services/whisper-stt/README.md.

Per-deploy workflow we follow

For every meaningful change:

  1. npm test && npm run typecheck && npm run lint && npm run build — must all pass
  2. Playwright against a throwaway Postgres (see CLAUDE.md), never against production
  3. git commit -m "feat(scope): ..." — conventional commits
  4. git push origin main — the GitHub integration builds and deploys production; CI runs lint, typecheck, unit, build, the bundle-size budget, gitleaks and npm audit (the Playwright job is switched off on CI, so step 2 is the only E2E run)

See ARCHITECTURE.md for system diagrams, docs/OBSERVABILITY.md for production monitoring/alerting setup, docs/README.md for the index of ops docs and production controls, docs/DEMO_GUIDE.md for live demo walkthroughs, and PITCH.md for the YC pitch.


🔐 Security

  • Secrets — never committed; .env.local is gitignored. Real secrets live only in Vercel env + Fly secrets.
  • PII boundaries — customer phone numbers are stored in Neon for re-send capability but never sent to LLMs or STT providers, never logged in plaintext (only last-4 in CSV exports / log lines).
  • Webhook auth — Razorpay webhooks (platform and per-vendor storefront) verified via HMAC-SHA256 with crypto.timingSafeEqual.
  • HTTPS only — Strict-Transport-Security (2 years, includeSubDomains, preload) is set in next.config.mjs alongside the CSP; AUTH_TRUST_HOST=true lets Vercel's proxy work for Auth.js.
  • Tenant isolation — every Prisma where clause includes vendorId. Helper requireVendorRole(role) returns the resolved vendor and throws on cross-tenant access.

Description taken from the repository README.

Ratings

–
0 ratings
5 0
4 0
3 0
2 0
1 0

Rate this app

Sign in to rate

Comments 0

Sign in to comment

No comments yet.

Related apps

#voice · #billing · #payments