LabFlow
com.aoneahsan.labflow
LabFlow is a multi-tenant Laboratory Information Management System (LIMS) spanning three production surfaces — React web, Capacitor mobile, and Firebase Functions — built for clinical labs with strict tenant isolation, a Draft→Reviewed→Approved→Released result workflow, audit trails, and HIPAA-conscious data handling.
At a glance
- Category
- full-stack
- Status
- Live
- Started
- Feb 2025
- Last updated
- 4 days ago
Identifier
com.aoneahsan.labflowPreview
Take a look before you go
The still below is painted first, then the running site loads behind it — so the dialog is never an empty rectangle waiting on a network round trip. Where a site allows framing the live app takes over; where it refuses, the still stays and says so. Nothing is requested until you press.
About
What this actually is
A tube arrives at the front desk with a name written on it.
From that moment every step is a chance for the name and the tube to come apart. Accessioning. The run. The read. The signature. The release to whoever ordered it.
A laboratory is a chain of custody before it is anything else.
Software that treats a result as a row in a table has already dropped the part that matters, which is not the value in the field but the question of who is allowed to say that value is final.
LabFlow runs on the Firebase free tier wherever Firestore security rules can enforce the policy, and reaches for Cloud Functions only where a rule genuinely cannot.
That line is drawn on purpose. A rule runs on every read and costs nothing; a function is a bill and a cold start.
Multi-tenancy makes the question sharper still. A list query has to prove its own tenant from its own filters, because a rule inspecting a document cannot rescue a query that asked for everything, and the difference between those two is invisible to a green build.
Patient and order management, sample accessioning and tracking, results entry and validation, billing, inventory, quality control and equipment integration.
Results move Draft, then Reviewed, then Approved, then Released. A role gates every transition.
Every patient record, order and result is tenant-scoped and audit-logged, so the question of who changed what has an answer that does not rely on anybody remembering.
Three production surfaces share one tenant model: a React web application, a Capacitor mobile build and Firebase Functions.
Underneath them sits one domain-service layer of 151 services, 28 Zustand stores and 60+ page modules.
It exists so that three surfaces cannot drift into three different definitions of what approved means.
The mobile build keeps core workflows usable offline through Dexie and IndexedDB, because a collection round does not stop where the signal does.
Then the costs, which in this domain are mostly about restraint.
A status machine that refuses is a status machine people will try to route around. So it has to be strict enough to be worth having and loose enough that the laboratory does not quietly start keeping a parallel spreadsheet, and that balance is a product judgement rather than a technical one.
Tenant isolation fails silently.
A correct rule and an over-broad query look identical from the outside, and the only defence is that every list read carries its own tenant filter and an explicit limit. That is checked by reading the queries, not by watching the build go green.
No patient identifier reaches a log or an error report. That is right, and it means a production incident tells me less than it otherwise would, so reproducing one takes longer.
Offline work means conflicts, and conflicts mean somebody has to decide which version of a result is the real one.
No iOS. There is no Apple Developer account behind this work, so the web and Android are the two surfaces it actually reaches.
The workflow is the product. Everything else listed above is scaffolding around one rule: a result does not leave the laboratory until a person with the authority to release it has said that it can.
Worth knowing
- Three production surfaces share one tenant model — web, Capacitor mobile, and Firebase Functions, with 151 service files and 28 Zustand stores behind them.
- Free-tier discipline: Firebase Functions are used only where Firestore Security Rules cannot enforce the policy — keeping the architecture predictable-cost for SMB labs.
- Build-time AEO: a custom Vite postbuild-SEO plugin emits 25 per-route static HTML files (with real per-page meta + a `<noscript>` answer block) and 24 Open Graph SVGs, so AI crawlers (GPTBot, ClaudeBot, PerplexityBot) read the content without executing JS.
- PWA + offline-first: the generated service worker precaches 446 entries (~11.5 MB); core workflows run offline via Dexie/IndexedDB and replay on reconnect.
- React 19 + React Compiler + Rolldown-Vite 8 — a genuinely modern, fast build chain (build dominated by Babel/React-Compiler ~77% + terser ~22%, ~5 min for the whole multi-route app with PWA + SEO generation).
- HIPAA-conscious by construction: PHI is kept out of logs/errors/analytics, Sentry payloads are sanitized, PrivacyScreen is on by default on mobile, and patient queries are role-gated.
- Honest about state: automated tests were intentionally removed (owner tests manually); store listings/version-sync are pending/unreconciled — tracked, not hidden.
Built with
- React 19
- TypeScript
- Vite 8
- TailwindCSS
- TanStack Query
- Firebase
- Cloud Functions
- CapacitorJS
Key features
What it does, and what that costs to build
Each of these is a capability the stack genuinely provides. None of them is an outcome nobody measured — there is no "cut onboarding by 40%" on this page, because no one measured onboarding.
- Full specimen lifecycle (accession to release)
- Role-gated Draft->Reviewed->Approved->Released workflow
- Multi-tenant isolation + audit trails
- Billing, inventory, quality control
- Offline-first mobile via Dexie/IndexedDB
- HIPAA-conscious data handling (no PHI in logs)
Screenshots
5 slots, 2 of them filled in
These are designed frames, not pictures. Each one records what belongs in the slot and at what width; the capture itself is taken from the running app. Drawing a fake screenshot here would put an image on the site that no build has ever produced.
Timeline
Still being worked on
Feb 2025
Work started
The earliest month on record for LabFlow.
Oct 2026
Last change
Status is completed — 4 days ago. Ongoing, so this row moves whenever something lands.
Questions
Common questions
The questions that actually arrive, answered in the first sentence.
- Who built LabFlow?
- Ahsan Mahmood built it alone, and it is live at labflow.aoneahsan.com. One person designed the tenant model, wrote the security rules that hold one laboratory's records away from another's, built all three production surfaces and wrote the domain-service layer they share.
- What does the LabFlow result workflow enforce?
- A result moves Draft, then Reviewed, then Approved, then Released, and each transition is gated by role rather than left to convention. Nothing reaches the ordering clinician until somebody with the authority to release it has done so, and every step is written to an audit trail. The order cannot be skipped, which is the entire point of encoding it in software instead of in a habit.
- Does LabFlow work on iPhone?
- No. LabFlow ships a web application and a Capacitor mobile build for Android, and there is no iOS build because there is no Apple Developer account behind this work. A laboratory running iPhones would use the web application, which is responsive, rather than an installed app.
- How is one laboratory's data kept separate from another's?
- Every patient, order and result is tenant-scoped, and the security rules enforce that on every read rather than the interface hiding what it should not show. The part that matters is that a list query has to prove its own tenant from its own filters — a rule that inspects a document cannot rescue a query that asked for everything, and that specific mistake is invisible to a passing build.
- Does LabFlow work without a network connection?
- The mobile build keeps core workflows usable offline through Dexie and IndexedDB, so collection rounds do not stop where the signal does. Anything that has not been loaded yet is not available while offline, and the interface says so rather than showing an empty screen.
Keep looking
More full-stack products
- CL
ClearHire
com.aoneahsan.clearhire
A hiring platform built around one idea: employment claims should be checkable. Resume builder, candidate and company workflows, a verified-employment system, and 50+ career tools.
- TR
Trizlink
com.trizlink.app
Branded short links, link-in-bio pages, click analytics and a suite of utilities.
- SL
SlackVault
com.aoneahsan.slackvault
Exports and archives Slack history so a workspace outgrowing its retention limit keeps its own record.