Internal & investor material. Sign in with your @qiri.ai Google account to continue.
What each surface does today, what it runs on, and where it sits in delivery. One backend, one schema; every surface is a thin client on the same platform, and every clinical action lands in the same audit trail.
The Phase 1 wedge: clinical review and dispensing for the pharmacist, live at console.qiri.ai. Next.js on Cloud Run, Firebase auth, branded per-org sign-in.
| Area | What the pharmacist can do |
|---|---|
| Scripts queue | Triage every script in review as a board or list (/scripts). Intake snapshots each script locally so the queue renders without a platform round-trip. Every intake path (app-lodged, manual, eScript, QR, paper) lands straight in the queue; a per-site setting decides whether Qiri screens each script on the way in. A script that arrives unscreened is marked as such, and the pharmacist can approve or refuse it as-is or run a screen on demand. |
| Review canvas | One screen per script (/scripts/[id]): the reasoning engine's verdict and each check it ran, the interaction matrix, counselling points, CMI, and a clinical note. Drug lookup autocompletes against the platform dictionary; manual entry uses a guided medicine picker that offers only the strength, form, and brand combinations that really exist for the drug. |
| SIG, in plain English | The pharmacist's SIG shorthand ("1 m") renders live as patient language ("Take 1 in the morning") on the review screen and on the printed label; low-confidence expansions are flagged instead of guessed. |
| Sign-off | Approve, amend, or override. Any un-decided script can be edited, with the edit screened and the full amendment chain rendered on the immutable record (script_amendment, append-only). A pharmacist can override a BLOCK verdict with a traced justification; a technician cannot. |
| Outcome to the patient | When the script came from the patient app, the sign-off stamps the decision back onto the submission (approved or not approved) and, if the patient opted in, sends a generic OS push. No PHI leaves the pharmacy; the app never fabricates a status. |
| Dispense label | Label output with the plain-English SIG, plus the AU Base identifier panel (ETP, IHI, Medicare, DVA, date signed, PBS claim status) for the audit trace and future write-back. |
| Ask Qiri | Streaming clinical Q&A on the live engine, grounded in the open patient context, with suggested next questions. Counselling, CMI, and Ask Qiri answers translate on demand. |
| Consults | Booking, recurring availability, consult records; private video consults are transcribed in-region (Google STT v2, australia-southeast1) with the transcript surfaced on the record and a bad transcript refused rather than trusted. Consent explicitly covers transcription as well as recording. Paid consults collect through Stripe Connect on the pharmacy's own account, gated on the consult_payment entitlement. |
| Records & registers | An S8 controlled-drugs register view, a dispensing ledger with days since last supply, a PBS-safety-net tally for the year on the patient record, and MedsCheck records with an authorship rule. |
| Patient records | Duplicate-Medicare prompt at intake, with the Medicare card treated as a household key, never a person match on its own. Record merges are audited and carry consults; a needs-linking queue catches consults that lost their patient. |
| Administration | Org and site settings, users and roles (including the counter-only customer_assistant role), entitlements and pricing acceptance, restricted list, stock. |
Nothing dispenses without a licensed pharmacist's sign-off. The engine proposes and checks; the symbolic gate enforces hard ceilings; the pharmacist decides. Every decision writes a structured trace: inputs, sources cited, rules fired, model used, pharmacist action.
Qiri is the register as well as the clinical record. A dispense order is one basket holding scripts and OTC lines, payable at the counter or online, with PBS pricing and GST handled per line.
| Piece | How it works |
|---|---|
| Dispense orders | dispense_order + dispense_item: scripts and OTC products in one basket. The box QR printed at dispense carries the order's pay link. |
| In-store counter | /counter is a standalone POS page: scan the box QR, the basket loads, take payment by card (Stripe Terminal, direct charge on the pharmacy's connected account), cash, or a split across tenders (cash plus card, or two cards). The whole tender flow stays inside the payment modal, with statement-style totals. Runs under the counter-only role, gated on the pos_payment or dispense_label entitlement. |
| Till sessions | The cash drawer opens against a float; every cash tender lands in the session; reconciliation counts the drawer and closes the session with any variance recorded. |
| Tablet till | The Counter installs as a chrome-free web app on a tablet: 44px touch targets, a glass top bar with a full-height cart rail, and camera barcode/QR scanning where there is no wedge scanner. |
| Online payment | /pay/<token> is a public page: the patient sees the basket and total and pays with Stripe Payment Element. The unguessable token is the credential; no account needed. |
| PBS pricing | The pbs_item reference table prices subsidised lines; patient contribution and GST are computed per line, not per order. |
| Refunds | Full or partial, with attribution (who refunded, when). Refunding an OTC line restocks it by default; the toggle is per refund. |
| Stock linkage | Payment decrements stock; refund restocks it. Every movement lands in the append-only ledger with a reason code, so the register and the shelf never drift silently. |
Per-site inventory with an append-only movement ledger (stock_movement). Every mutation has a reason: dispense, otc_sale, refund_restock, manual_adjust, import, received, stocktake. Admin-gated under Settings → Stock.
| Tab | What it does |
|---|---|
| List | Search, sort, and edit the product file inline: price, cost (with a below-cost alert), GST, PBS linkage, poisons schedule, reorder point; per-item sale history. |
| Add & import | Single-item form or bulk CSV import (code, name, strength, on-hand, price). |
| Reorder | Everything below its reorder point; export a wholesaler CSV or raise a purchase order in one step. |
| Receive | Book in a delivery: scan or search, set quantities, supplier reference; on-hand rises and the ledger records it. Ad-hoc receiving requires a supplier and records the payable, so nothing arrives off the books. |
| Batches & expiry | Batch and expiry tracking per stock line, with first-expired-first-out (FEFO) pick suggestions at dispense. |
| Stocktake | Cycle-count reconciliation: count a shelf, the variance writes stocktake movements to the ledger, on-hand trues up. |
| Orders | Purchase-order lifecycle: create from the reorder list, adjust lines, send, then receive against the order to close it. |
| Forecast | Suggested reorder points from actual sales history; tune the assumptions (history window, buffer days, coverage per order) and apply to selected items. |
Stock lines correlate to the drug dictionary by AMT code, so the review screen can show whether the drug being signed off is on the shelf. Scripts capture the same code at intake (the guided medicine picker and searched stock adds both land a pack-level AMT code), closing the stock-to-script loop.
Every economic event a bookkeeper reconciles lands once, at the moment it really happens, in an append-only ledger (accounting_event) with the tax and revenue splits an Australian pharmacy BAS needs. The register and the shelf are the sources; accounting is a downstream reader, so it can be built, replayed, or swapped without touching the till.
| Piece | How it works |
|---|---|
| What it records | A sale when a dispense order or consult settles, a refund when one reverses, a bill when stock is received against a purchase order. Amounts are signed cents; each row carries gross / tax / net, patient / PBS-government, and taxable / GST-free splits, so the daily journal needs no re-derivation. |
| Daily takings | Settings → Accounting shows takings by day; /api/accounting/summary is the read. |
| Export | A vendor-neutral CSV journal (/api/accounting/export) covers Xero and MYOB today, with the tax-treatment column each expects. |
| Direct sync | Xero and MYOB adapters are scaffolded (tax-code maps in place) but not yet connected; posting straight to each platform's API is the next step. Until then the CSV is the bridge. |
React Native (Expo) app for iOS and Android: a scripts wallet, consult booking, and payments. Core flows run end to end against the live platform, and internal builds are on TestFlight and Play internal testing. It stays in build until the clinical identity link lands.
| Tab | What the patient can do |
|---|---|
| Home | Next-action dashboard: the script awaiting a pharmacist's decision or a payment, the order to collect, the upcoming consult. |
| Cabinet | The scripts wallet: add an eScript by QR scan or token entry, send it to a pharmacy, then track the pharmacist's decision and pay when it's approved. |
| Consults | Book and attend a private video consult with a pharmacist; card-on-file payment. A free consult skips the payment card entirely; an ended consult closes out rather than lingering as booked. |
| Notifications | A server-derived inbox: notices are computed from real platform state (decision, payment, collection), so the feed survives reinstalls and second devices and is never fabricated client-side. |
| Settings | Profile, consents, PIN and biometric lock (15-minute auto-lock), payment methods, notifications, and account deletion. |
Onboarding covers sign-in, a hard email-verification gate, PIN + biometrics, ASL linking, and split consent (Patient Terms, Privacy, ASL access). On the platform side the app sends a script to a pharmacy at /api/patient/scripts/<org-token> and polls /api/patient/scripts/status/<id> for the outcome; it manages its own record through /api/patient/profile and /api/patient/consent, and books and pays via /api/book/<token> and /api/pay/<token>. Patient calls carry a Firebase token scoped to the dedicated patient identity surface; the x-qiri-app-key header bypasses the booking Turnstile as a stopgap.
Patient identity is deliberately two records: patient_profile is the app account (self-service, with an audit-grade consent ledger that stamps the document version, a prose hash, and the acceptance context on every grant); clinical.patients is the dispensing record. They share no key; the linkage is a controlled Medicare + date-of-birth match, and it is the remaining release gate.
Sign-in, email verification, the self-service profile, and the consent ledger are live server-side. What is not yet built is the clinical identity link that resolves an app account to its dispensing record, a Phase-2 platform concern; until it lands, a script the platform can't resolve is shown as unresolved, never faked. Demo mode runs on in-memory stores and never ships in a real build.
Standalone secure dispensing units with remote pharmacist oversight from a central command centre. The kiosk runs an offline-tolerant edge runtime; hardware comes from an OEM partner, not a Qiri factory.
The design intent, edge behaviour, and hardware envelope are covered in Architecture → Kiosk edge & hardware; procurement and open hardware decisions are tracked in Roadmap & decisions.