Give your agent a wallet you control.
에이전트가 일회용 카드나 기계 결제 프로토콜로 온라인 결제하고, 모든 요청을 직접 승인
인도 의료점포용 청구·재고·GST·계정 관리와 WhatsApp 청구, 오프라인 결제 지원, 7일 무료
Billing with FEFO batches, expiry control, purchases, GST and accounts, WhatsApp invoices and offline billing for Indian medical stores and small chains. Runs on infrastructure you control. 7-day free
금융TypeScript · HTMLGitHub @sumitgoxlofficial-jpg온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Billing with FEFO batches, expiry control, purchases, GST and accounts, WhatsApp invoices and offline billing for Indian medical stores and small chains. Runs on infrastructure you control. 7-day free trial.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Smarter Pharmacy. Simpler Business. Pharmacy management for Indian medical stores and multi-branch chains: billing, batch inventory, expiry control, purchases, accounting, WhatsApp invoices and encrypted backups. The pharmacy's data stays on infrastructure the pharmacy controls.
Status: every screen in the design handoff (
design/) is built. The app ships with no demo data: a fresh install opens the setup wizard, where you create your pharmacy, branches and owner account. Integrations that need outside accounts (WhatsApp Cloud API, Google Drive, SMS OTP, remote OCR, a local LLM) work once you add your own credentials in.envor in the app; until then the screens say they're not connected.
Next.js 15 (App Router) · React 19 · TypeScript strict · Tailwind 4 · Prisma 6 · PostgreSQL 16 · Zod · Vitest · lucide-react.
cp .env.example .env # set DATABASE_URL and SESSION_SECRET (32+ random chars); never commit .env
pnpm install
pnpm prisma migrate deploy # creates tables + append-only triggers
pnpm dev # http://localhost:3000 → setup wizard on first run
With Docker instead: bash scripts/lan-setup.sh && docker compose --profile https up -d --build (see docs/DEPLOYMENT.md).
Tests (unit + integration against a real PostgreSQL; uses TEST_DATABASE_URL, default medoro_test on localhost):
pnpm test
pnpm lint && pnpm typecheck
End-to-end (Playwright, e2e/): needs a production build, an empty migrated database and the server environment (SESSION_SECRET, HOST_KEY, OTP_PROVIDER=console, STAFF_BOOTSTRAP_EMAIL, …); see docs/TEST_PLAN.md.
pnpm prisma migrate reset --force && pnpm build
pnpm test:e2e # starts `next start` itself; add a file or -g filter to narrow
| Area | Notes |
|---|---|
| Website & legal | Marketing site at / (product, AI, data ownership, pricing, FAQ) and /legal (about, help, privacy, terms, refunds, cookies, DPDP, grievance). Legal text is a draft for lawyer review |
| First-run setup | Pharmacy (GSTIN/drug licence checks), owner account, where PostgreSQL runs (this server, shop LAN or hosted, checked against DATABASE_URL) with a connection test, branches & counters, team invite codes, backup recovery kit (key generated in the browser, sealed on the server; a printable kit page with the key as text and a QR code) |
| Sign-in | Email + password (Argon2id), TOTP two-step verification (required for owners/managers, "trust this PC" for 30 days), lockout after 5 failures. Mobile OTP when OTP_PROVIDER is set. Counter staff: pharmacy code + employee ID + PIN + counter |
| Live multi-device sync | A sale, stock receipt or voucher on one device shows up on every other open screen within about a second (Postgres NOTIFY → one listener per app server → server-sent events → screen refresh, keeping carts and forms). The header pill shows Live / Connecting / Offline |
| Install & offline billing | Installable app (manifest, icons, service worker) in Chrome/Edge or on Android. A manager turns on offline billing per counter in Sync & offline: the counter keeps the price list and a reserved share of each batch (split between offline counters, one share left for online ones). If the server can't be reached, Medoro opens offline billing: cash/UPI/card bills with provisional receipts, kept on the device. On reconnect they post automatically with their original time and a real invoice number; the server rechecks stock, prices and permissions, and anything that no longer fits becomes a conflict a manager posts from current stock or closes with a note. Needs HTTPS (browsers only run service workers on secure sites or localhost) |
Desktop app (desktop/) | Tauri app for Windows, macOS and Linux that opens your Medoro server in its own window (it stores only the server address). Installers are built by the "Desktop app" GitHub workflow; tag desktop-vX.Y.Z to draft a release |
| App shell | Permission-filtered nav with live badges, branch switcher, EN/हिंदी, "View as" role preview (narrows only), sessions & revoke |
| Dashboard | KPIs, 14-day sales, collections, insights, low stock, expiring batches, branch performance, backup status, activity |
| Billing (POS) | FEFO batches, Rx prescriber rule, discount caps, split payments, credit limits, loyalty points (earn and redeem), held carts, idempotent commit, thermal/A4 invoices, WhatsApp send, B2B tax invoices (buyer GSTIN, place of supply, IGST for other states) |
Built into the core: money in integer paise with GST back-calculated from MRP, FEFO batch allocation, a hash-chained audit trail, and database triggers that make stock movements, vouchers, sales and audit rows append-only.
| Path | Purpose |
|---|---|
src/app/(auth) | Setup wizard, sign-in, MFA, employee login |
src/app/app | The signed-in app (one folder per screen) |
src/domain/* | Business rules and services, shared by the UI, API routes and the AI assistant |
src/staff, src/app/staff | Medoro staff console (control plane): its own auth, tables and services |
src/app/page.tsx, src/app/legal | Marketing website and legal pages |
src/server | DB client, sessions, audit, sequences, secret sealing |
src/lib | Money, dates, i18n, navigation |
prisma/ | Schema and migrations |
tests/integration | Service tests against PostgreSQL |
e2e/ | Playwright end-to-end specs (setup wizard first, then one spec per area) |
design/ | The original clickable prototype, assets and handoff notes (reference only) |
docs/ | Architecture, security, privacy, data ownership, AI, WhatsApp, orders & delivery, GST compliance, testing, deployment, backup, purchasing & money (pricing, e-bills, claims, cheques, bank) |
Medoro does not claim GST, drug-law or DPDP compliance, or any official government integration. Have qualified professionals review it before launch.
| Orders & home delivery | Phone, WhatsApp and counter orders with stock shown per item, prescription photo, address, date/slot and payment (cash on delivery, prepaid UPI, credit). New → confirmed → packed (billed through the POS commit with FEFO batches) → out for delivery → delivered, or cancelled/returned (bill voided or credit-noted, stock back). Delivery role with a phone screen (call, navigate, delivery code or receiver's name, cash/UPI collected), rider cash handover into the drawer, customer updates on WhatsApp templates or SMS. See docs/ORDERS_AND_DELIVERY.md |
| Owner view & report emails | Phone-sized /app/owner: today vs yesterday by branch, cash per open drawer, cash with riders, low stock, expiring, approvals waiting, backup health, alerts, quick actions; PWA shortcut. Daily or weekly report emails (sales summary, GST, low stock, expiring, dues) with CSV attachments, per-recipient unsubscribe links, audited |
| Returns & shift | Returns against invoices (restock or damaged), credit notes, refund modes, shift open/close with cash difference posted |
| Data import | Medicines with opening stock, suppliers and customers from Excel (.xlsx) or CSV. Every row is checked first with a reason for each problem; nothing is saved until all rows pass; re-running a file skips what's already there |
| Inventory | Batches, receive stock (opening stock posts to Inventory against Opening balance equity), per-batch actions (stock adjustment +/− with reason, write-off, return to supplier, transfer request, quarantine/release), a Transfers tab to approve/receive/reject/cancel inter-branch transfers, movement ledger, stock count, recalls with one-click supplier return, expiry prevention |
| Salts & substitutes | Each medicine has a composition (salts with strengths, e.g. Paracetamol 500mg + Caffeine 25mg) and an order-independent key. The POS finds brands by brand, salt, squashed brand (dolo650) or a typo (trigram similarity); an out-of-stock item, or F6, opens “Substitutes in stock” sorted by price per unit or margin; the medicine drawer lists them too. Import a “Composition”/“Salt” column, or load the bundled sample of ~60 common Indian brands from Inventory → Salts (see docs/CATALOG.md) |
| Loose sale (multi-unit) | Pack definition per medicine (1 box = 10 strips, 1 strip = 15 tabs, sell loose). Stock is held in the smallest unit; the cashier picks strip or tab (F7); a tab sells at MRP ÷ 15 rounded down to the paisa so a strip sold loose never exceeds MRP. GRN and opening stock receive in packs or cases; returns, counts (2+5), transfers, expiry and valuation show packs plus loose remainder; offline billing carries the pack sizes |
| Racks | Catalogue rack plus a per-branch override, shown in POS search and on count sheets (filter by rack, shelf order, printable sheet) and filterable in Inventory |
| Doctors & referrals | Doctor master (name, qualification, registration no., clinic, phone, address). The POS prescriber is a doctor picker with quick-add (typed names still work); bills keep the prescriber text and link the doctor. Sales by doctor for any period and branch, on screen and as CSV |
| Barcode labels | Code 128 and EAN-13 SVG (no dependencies) on 50×25 mm thermal or A4 3×10 sheets with name, batch, expiry, MRP and rack. Items without a barcode get an in-store EAN-13 (29… + check digit) that scans at the POS |
| Stock intelligence | Reorder forecast and draft POs, seasonal planner (after 12 months of sales), supplier price comparison on landed cost (after schemes and discounts), margins on landed cost by item, category and supplier plus margin on stock in hand, slow stock, anomaly review, central buying across branches (one view per supplier with each branch's quantity, draft POs for every branch in one click) |
| Purchases | POs (place, cancel or close short with a reason), supplier invoice review with a queue of uploaded invoices to open or discard (manual entry; remote OCR optional), GRN with totals check (supplier invoices need the printed total and must match it within ₹1; low-confidence OCR lines must be ticked as verified, checked on the server), IGST for out-of-state suppliers. PO and GRN lines carry PTR, PTS, MRP, free-goods schemes ("10+2") and scheme / trade / cash discount %; landed cost per unit spreads free goods; GST base (after discounts, before cash discount, or on PTR) and input-credit vs composition are pharmacy settings. Distributor e-bill import (CSV, Excel, pipe/tab text) with header detection, a column mapper saved per supplier, and matching by barcode, learned supplier codes/names, then name + pack. See docs/PURCHASING.md |
| Claims to suppliers | Expiry, near-expiry, breakage and wrong-item claims: stock leaves at once into Supplier claims receivable; acknowledged → credit note received (partial credits, shortfall written off with a reason) or rejected; aging per supplier; near-expiry suggestions inside each supplier's return window |
| Suppliers & customers | Consent per purpose (invoices vs offers) and channel (WhatsApp, SMS) with history, balances, payments, ledger statements for any date range (screen, print, CSV), delivery accuracy from POs vs GRNs, credit limits, customer GSTIN (checksum-validated), place of supply and billing address, expiry-return window per supplier |
| Cheques | Cheque receipts and payments (post-dated allowed) through Cheques in hand / Cheques issued clearing accounts; deposit, clear, bounce (party balance restored, charges booked, supplier bills reopened); due-cheques dashboard card and badge; audited |
| Bank reconciliation | CSV/Excel (.xlsx, and banks' HTML/XML .xls) bank statement import with column detection or a saved mapping, duplicate-safe re-imports, auto-match by amount, date ±3 days and cheque/UTR reference, manual match/unmatch, unreconciled report (CSV) and statement vs book balance |
| UPI & Bank Connect | Financial Management → UPI & Bank Connect, and UPI & Bank on Drive counters. Works with the pharmacy's existing bank, UPI ID and QR (no payment gateway). Statement upload for any bank; UTR/RRN, UPI ID and payer read from narrations; duplicate checks across files (fingerprint, UTR, attributes; doubtful ones go to review); credits matched to credit bills (Medoro reference from a UPI QR on the shop's own UPI ID, UTR, invoice number automatically; amount only as a suggestion), part payments, several payments per bill, undo; UPI taken at the counter checked against the bank, with "not in the bank statement" alerts; reports (daily, monthly, bank-wise, by channel, unmatched) as Excel, CSV or print. Bank APIs, Account Aggregator, PhonePe, Paytm and BharatPe are listed with their real status (partner onboarding required / not supported). See docs/UPI_BANK_CONNECT_PLAN.md |
| Accounting & reports | P&L, day book, account ledger with running balance, trial balance, expenses, reversals (never edits), GST summary with CGST/SGST/IGST, twelve CSV reports for your CA, including the HSN summary and the Schedule H1 register (H1, X and NDPS sales with patient and prescriber, also on screen) |
| GST returns & Tally | Accounts → GST returns, per GSTIN and month: GSTR-1 JSON for the GSTN offline tool (B2B, B2CL, B2CS, nil, CDNR/CDNUR, HSN B2B/B2C, documents) with a CSV summary, GSTR-3B (3.1, 3.2, ITC 4A/4B) on screen, CSV and JSON, GSTIN- and branch-wise roll-up, Tally Prime masters and vouchers XML with an editable ledger map. See docs/GST_COMPLIANCE.md |
| E-invoice & e-way bill | NIC IRP (direct, AppKey/SEK encryption) or a GSP: IRN with signed QR on the invoice, cancel within 24 h, e-way bills for B2B invoices and branch transfers. Off until EINVOICE_* is set and the owner turns it on |
| WhatsApp & messaging | Meta Embedded Signup (or pasted credentials), invoice PDF or link sends with delivery status, retry worker with backoff, invalid-number and revoked-token handling, signed webhook, STOP opt-outs, refill, feedback and payment reminders, store updates and campaigns, SMS fallback (MSG91/Twilio/HTTP with DLT templates), credit notes on WhatsApp; marketing and SMS sends honour the per-purpose, per-channel consent above, and a STOP reply withdraws both purposes on that channel with a consent record |
| Loyalty | Points per ₹100 paid, redemption at Billing as a tender, proportional reversal on returns and voids, expiry, history on the customer, points on the receipt |
| Backup & restore | Encrypted backups (AES-256-GCM, recovery-kit key), verification, Google Drive upload, daily schedule with retries. Full restore: loads into a test copy first, shows backup vs live, takes a safety backup, then swaps in one transaction after the owner types the pharmacy code |
| Users & branches | Roles matrix, per-user permission overrides on top of the role, invites, PIN/password resets, branch management, transfers overview, audit trail with chain verification |
| Sync, subscription, privacy | Devices, offline counters and bills, plan status, full data export (JSON, or a ZIP with one CSV per table), customer erasure, strict mode enforced on the server (masked customer phones below manager, exports with phones only with a reason, no telemetry or remote AI), daily retention clean-up with a dry-run preview, opt-in anonymous telemetry and scrubbed crash reports, grievance officer printed on invoices |
| Subscription & licensing | Set LICENSE_SERVER_URL + LICENSE_PUBLIC_KEY and the install registers with Medoro's licence server (the staff console) on its first check-in, starting a 14-day trial from setup. It checks in hourly from the built-in scheduler (daily from a host cron) and when Subscription, Help or Privacy is opened, sending only the app version, branch and counter counts and the requests you make; each answer is a licence signed with Ed25519 and verified before it's stored. Trial or paid period → 7 days' grace with a banner → read-only: sales, purchases, stock changes and messages are refused on the server while sign-in, viewing, exports, backups and restore keep working. Offline, the last signed licence applies; with no licence server configured nothing is limited. The Subscription page shows real status and days left, UPI QR / bank details with a reference (PAYMENT_UPI_ID, PAYMENT_PAYEE, PAYMENT_BANK), "I've paid" reporting, AI add-on and cancellation requests, and Medoro invoices delivered with the licence. Help is a support inbox: tickets go to the console and replies come back. Keys: node scripts/licence-keys.mjs |
| Website trial sign-up | "Start free trial" opens /start: a validated, rate-limited lead form (with a honeypot) that creates a website lead in the staff console and explains next steps; on an empty server it also links to setup |
| Support access | The owner gives Medoro support a single-use link (1, 2 or 4 hours) from Privacy & data, or approves a request support sent from the console (the link then goes to support automatically). It signs in a dedicated "Medoro support" user that can look but not change or download anything (enforced on the server), shows a banner, is audited, and can be ended at any time |
| AI assistant | Drawer (Ask AI / Ctrl+J) that answers from registered tools over the same services, with the same permissions; English, Hindi and Hinglish; refuses clinical questions; batches, reports, and write actions (draft PO, expense, stock adjustment, refund, backup) only after a single-use 5-minute confirmation that re-checks current data. Rule-based by default; AI_MODE=local plans with an Ollama model, AI_MODE=remote with an OpenAI-compatible endpoint (owner opt-in, never in strict mode, names redacted). Can be switched off per pharmacy or with AI_ENABLED=0. See docs/AI_ASSISTANT.md |
| Deployment & operations | docker compose stack (PostgreSQL 16, one-shot migrate job, app with healthchecks, optional HTTPS proxy), shop-LAN helper (scripts/lan-setup.sh/.ps1: local CA + certificate, .env with random secrets, URLs), /api/health, /api/ready (DB, migrations, settings), Prometheus /api/metrics behind METRICS_TOKEN, JSON logs with redaction, refuses to start with pending migrations. See docs/DEPLOYMENT.md |
| Security hardening | Per-request nonce CSP and security headers, Origin checks on server actions and cookie-authenticated API posts, PostgreSQL-backed rate limits (AI, WhatsApp sends, campaigns, exports, reports, documents), version checks on medicine/supplier/customer edits, two-tenant isolation test suite, CodeQL, Dependabot and a CycloneDX SBOM in CI. See docs/SECURITY.md |
Staff console (/staff) | For Medoro's own team: sign-up with super admin approval (first admin from STAFF_BOOTSTRAP_EMAIL), password + mandatory authenticator, invites and resets, sales pipeline with discount approvals, logged sales with commission locked at the day's rate, payment verification creating customer accounts (and, for payments reported from a pharmacy's app, extending its paid-until date and issuing a Medoro invoice), encrypted payout bank details, payout runs with TDS, customers with health score (from live licence check-ins: last check-in, app version, branches, devices) and notes, licence keys, trial extensions, per-customer billing history with add-on and cancellation requests to approve, support tickets with SLA (tickets opened from a pharmacy's Help screen arrive here; replies go back to it), internal notes, escalation and remote-access requests the owner approves in their app. It is also the licence server (/api/license/*, signed with LICENSE_SIGNING_KEY). Staff tables are separate and never touch pharmacy data |