Changelog
KinetiRx changelog
What changed in each release. Full details and downloads are on the GitHub releases page.
v1.6.14
Fixed the Due Khata Collect action (DueKhataTab.tsx's handleCollectDue) recording a hardcoded stale date, '2026-08-17', as the record's last transaction date on every collected payment instead of the actual date the payment was collected — the only write path in the app still using a literal date instead of the shared getTodayISODate() helper. Backend retagged from 1.6.13 (no source change).
v1.6.13
Fixed distributor Address and Drug License (DL) number not being captured from purchase bills, across all four extraction paths: - InwardOCRTab.tsx's offline/online-OCR text parser (parseInvoiceTextLocally) declared an address variable on ScannedInvoiceData and even merged it into the distributor record on commit — but never actually extracted it from the OCR'd text anywhere, so it always stayed N/A and the merge was a no-op. dlNo didn't exist on the type at all, so DL number was silently discarded even when a bill's "DL No:" line was visible in the recognized text (it was actively pattern-matched as a *non-item* line and dropped, never captured anywhere). - The server AI path (backend/internal/handlers/ocr.go's Gemini prompt) already asked for address correctly, but never asked for dlNo — added. - The "Copy AI Prompt" text (added in 1.6.11, for the free-AI-chat paste workflow) never asked the AI to include Address or DL No, so that path couldn't carry them either even when a user retyped them into the reply. Added Address: and DL No: to the requested format, and the paste-text labeled-line parser now recognizes both labels.
v1.6.12
The free cloud OCR fallback (utils/puterOcr.ts, backed by Puter.js) is now on by default instead of an opt-in toggle. Previously, a fresh install with no GEMINI_API_KEY / AI provider configured would silently fall straight through to the least-accurate fully-offline Tesseract OCR on every upload unless the owner found and flipped the toggle in Settings or the Inward OCR tab — most installs never did, so most bills were being read by the path the changelog itself flags as unreliable on dense tables. Now the free cloud OCR path is tried automatically whenever there's an internet connection, before falling back to fully offline scanning; still toggleable off per-device if preferred.
v1.6.11
Added a "Copy AI Prompt" button to the Inward OCR tab's Paste Text panel. Copies a ready-made extraction prompt to the clipboard, formatted to match parseInvoiceTextLocally's labeled-line format exactly (DISTRIBUTOR:, GSTIN:, Phone:, INV NO: headers, then Name, Qty: x, Rate: x, MRP: x, Batch: x, Exp: YYYY-MM, Pack: x per item) — paste it into any free AI chat (ChatGPT, Gemini, Claude, Copilot, Meta AI, etc., no API key required) along with a photo or PDF of the bill, then paste the reply straight back into the box and it parses through with no manual reformatting. Backend unchanged; only the frontend image was rebuilt.
v1.6.10
Fixed two real bugs in the AI OCR / Vision Model feature added in 1.6.9, found immediately by a real user configuring their own Gemini key: 1. The Settings panel showed a "Gemini OpenAI-compat endpoint" link that pointed at Google's *documentation page* (ai.google.dev/gemini-api/docs/openai) right next to the Base URL field — easy to mistake for the value to paste. Pasting that link as the Base URL sent every request to a website instead of the API, which failed with an opaque "invalid character '<' looking for beginning of value" (the site's HTML response). The panel now shows the actual endpoint URL as copyable text and calls out the docs link as reference-only. 2. Separately, and more importantly: Gemini's OpenAI-compat endpoint wraps error responses in a JSON *array* ([{"error":{...}}]) instead of the bare object every other part of this API uses. Any real error from Gemini — bad key, wrong model, quota exceeded, not just the docs- link mistake above — hit the same raw unmarshal failure instead of surfacing Gemini's actual message ("Please pass a valid API key", etc). Both shapes are now handled, and a genuinely non-JSON response gets a clear "double-check the Base URL" hint instead of a raw parse error. Added regression tests for both response shapes.
v1.6.9
Added a Settings section ("AI OCR / Vision Model") to configure accurate AI-vision purchase-bill scanning and the clinical assistant without touching server environment variables: any OpenAI-compatible endpoint — Gemini's own OpenAI-compat endpoint, OpenAI itself, OpenRouter, Groq, a local Ollama vision model, etc. — not just Google's native Gemini API.
v1.6.8
Follow-up to 1.6.7 after re-testing the offline OCR fallback against the same two real invoices repeatedly: Tesseract's raw text output turned out to vary from run to run on the *identical* preprocessed image (confirmed by re-running it several times), so single-run testing wasn't catching every failure shape. Three more real bugs found and fixed from that wider testing: 1. When a line's HSN/Batch/ExpDt column anchors were *all* unreadable, the parser had no boundary to stop the "name" at and took every remaining token on the line — reproduced against a real bill where this created a medicine literally named "SVOCITA LS TAR HOOTON 20831 77828701 04727 20831 15643 400 0.00 $% 40 52" (the whole raw line, price columns included). Now rejects the row instead of guessing without any anchor at all. 2. The same missing-anchor case was also silently turning the GST-summary footer lines (SGST/CGST calculation rows) into fake medicine entries whenever OCR happened to garble "SGST"/"CGST" past keyword recognition but leave a plausible-looking decimal number nearby. Fixed by the same anchor requirement above. 3. MRP/Rate values over ₹5,000 (never genuine on any real sample invoice) are now treated as a dropped decimal point and recovered by dividing by 100 — e.g. a misread "20831" becomes 208.31 — instead of always being rejected outright, which is what was making the on-device fallback produce zero usable items on some real OCR passes even after the 1.6.7 image-quality fix. 4. The distributor-name letterhead match now accepts "DISTRIBUT" as a prefix instead of requiring the exact full word "DISTRIBUTOR" — OCR commonly drops the trailing 1-2 characters of a word on a real photographed letterhead, which a full-word match was missing outright.
v1.6.7
Fixed two real accuracy bugs in the on-device (fully offline, no API key) OCR fallback used by both Inward Stock bill scanning and patient-ID/phone scanning, found from two real distributor invoice photos that came back almost entirely garbled (distributor read as "C UMA MEDICINE DISTRIBUTOR" instead of "NEW UMA...", item names like "TEE", scrambled batch/rate columns): 1. The image sent to Tesseract was only ever downscaled, never upscaled — a bill photographed at a normal distance (long edge well under the 1600px cap) went to OCR at its native low resolution with color-channel JPEG noise still in place. Now normalizes to grayscale and upscales up to 2x (capped at 3200px long edge) before OCR. Verified against both real invoices: the same two bills that previously produced "N/A" distributor/GSTIN/phone and unreadable item names now correctly read the distributor name and every item name legibly. 2. The line-item parser's "does this line look like a table row" check only required one digit plus 3+ letters anywhere in the line — a short burst of OCR noise off the letterhead/logo could satisfy that as easily as a real row, and one real bill's garbled header noise ("4 a TEE") was silently accepted as a genuine line and created a fake "TEE" medicine (qty 4, ₹3 rate) in live stock. Now requires at least 6 tokens, well below what any real row in this column layout actually has (12-13), before attempting to parse a line as an item.
v1.6.6
Added an opt-in free/unlimited cloud OCR option for Inward Stock bill scanning, backed by [Puter.js](https://developer.puter.com/tutorials/free-unlimited-ocr-api/) (js.puter.com, no API key or backend wiring — the end user's own free Puter account covers usage). Off by default; toggle it from the Supplier Purchase Bill Auto-Scan (OCR) tab or from Settings. When enabled, a scan tries the paid server AI first, then Puter.js, then falls back to fully offline on-device OCR — each result is flagged with which path produced it so it's clear when to double-check the numbers before billing against that stock.
v1.6.5
Fixed the Inward Stock offline OCR fallback silently registering purchases under a generic "SUPPLIER DISTRIBUTOR" placeholder instead of the real distributor name. The distributor-letterhead detection only accepted an exact-shape match on the very first recognized line; real on-device OCR of a photographed bill routinely prepends/appends stray punctuation to that line (commas, em-dashes, misread border rules) or garbles it outright and pushes the real letterhead text down a line or two, and both silently fell through to the placeholder. Rewritten to search the first 8 lines, strip OCR noise characters from each candidate instead of requiring it to already be clean, and prefer a line containing a distributor-shaped keyword (DISTRIBUTOR, PHARMA, REMEDIES, etc.) over whichever plausible-looking line comes first — since a bill's buyer name is just as likely to survive OCR cleanly and would otherwise win by appearing first. Verified against the real tesseract.js output for two real distributor invoices: one now resolves to the exact correct name, the other to a close, easily-corrected match — both a large improvement over the placeholder they produced before.