The Health-Tech Engineering Checklist: What Has to Exist Before Your First Sample Ships
A phase-by-phase build checklist for diagnostics platforms, derived from six years running the engineering for a live biological age test.
2026-08-14 · By Filip Lauc
What has to exist before the first sample ships
Before a single kit leaves the warehouse you need four things in code: a kit identifier scheme that is printed and unique, a mapping between that identifier and a customer that the lab never sees, a chain-of-custody state machine for the sample, and a consent record timestamped before the kit is dispatched. Everything else can wait.
The kit ID is the decision that is hardest to reverse, because it is physically printed on tubes and boxes that are already in a warehouse. We treat it as two separate values: a human-readable kit code on the outer packaging that customer support can read over the phone, and a barcode on the sample tube itself that carries no customer information at all. The lab receives tubes and barcodes. The link between barcode and person lives in our systems, not theirs. When a lab technician scans a tube, they see a sample record with a collection date and a test type, and nothing that identifies a human being.
Consent has to be captured and stored before dispatch, not before result release, because the moment a biological sample is in transit you are already processing health data. We store the consent version, the exact text the customer agreed to, the timestamp, and the mechanism. Storing a boolean called consented is the single most common mistake we see in early-stage health-tech codebases, and it is worthless the first time anyone asks which version of the terms a 2023 customer actually accepted.
- • Kit ID scheme: outer human-readable code plus a separate PII-free tube barcode, both generated and reserved in advance of printing
- • Registration flow: the customer binds a kit code to their account, creating the only link between person and barcode
- • Sample state machine: registered, dispatched, collected, in transit, received at lab, in analysis, analysed, released, failed, resampled
- • Consent record: versioned text snapshot, timestamp, mechanism, and the ability to reconstruct what was shown on screen
- • Courier and cold-chain handoff records: tracking number, carrier events, and received-at-lab timestamp stored against the sample, not just the order
What breaks when the lab's LIMS is a spreadsheet or has no API
Assume the lab has no API. In practice, laboratory information management systems in small and mid-size labs are either a vendor product with a file-drop interface, an on-premise system with no external network access, or a shared spreadsheet. The correct engineering response is a bounded, versioned file exchange with strict validation, not a direct database connection.
The pattern that has held up for us is a manifest exchange. We generate a batch manifest of barcodes with expected test types when samples ship to the lab. The lab returns a results file per batch. Both sides are validated against a schema we own, and every file that arrives is stored verbatim before anything is parsed, so that a bad import can be replayed rather than reconstructed from memory. Rejected rows go into an exception queue that a human works through, because in diagnostics a silently dropped row is a customer who never gets a result.
Two failure modes are worth designing for explicitly. The first is the duplicate barcode, which happens when a lab re-runs a sample and issues a new row for the same tube. You need a rule for which run wins and an audit record of the superseded one. The second is the sample that arrives at the lab but never appears in any results file. Without a reconciliation job that compares dispatched barcodes against received results on a schedule, these samples disappear quietly for weeks until the customer emails support.
How result release gating works when a clinician has to sign off
Result release is a separate state from result availability. A result can be computed, stored, and visible to internal staff while remaining invisible to the customer. The gate is an explicit release action, recorded with the identity of who released it, when, and against which result version. Never derive customer visibility from the presence of a results row.
In practice the pipeline is: results imported and marked analysed, automated plausibility checks run, flagged results routed to a reviewer queue, unflagged results either auto-released or held depending on the market and product configuration. Which results require human sign-off is configuration, not code, because the answer differs by jurisdiction, by partner, and by whether the product is being sold direct to consumer or through a practitioner.
Partner and practitioner dashboards complicate this. A practitioner who ordered a test on behalf of their client often needs to see the result before the client does, so they can contextualise it. That means the release state is not a single boolean but a set of audience-scoped visibility flags. Getting this wrong is not a bug you patch quietly. It is a data exposure incident involving health data, so it belongs in the first release of the schema and in your test suite from day one.
Which of the 10+ systems can be deferred past launch, and which cannot
Only the systems that touch a physical sample or a legal obligation must exist at launch: order capture, kit registration, sample tracking, the lab exchange, result release, and consent. Warehouse automation, partner dashboards, business intelligence, and self-serve integration APIs can all be run manually or deferred, and usually should be.
The reasoning is asymmetric rework cost. A partner dashboard built six months after launch costs roughly what it would have cost at launch. An audit trail retrofitted six months after launch costs far more, because you now have historical records with no provenance, and no amount of engineering recreates who changed a sample status in March. The same applies to the kit ID scheme, the sample state machine, and consent versioning. These are the load-bearing walls.
Manual operations at launch are not technical debt if they are bounded and observable. For the first cohorts, a warehouse team packing kits from a filtered list and marking dispatch in an admin panel is entirely reasonable. What is not reasonable is that manual step happening outside the system, in a spreadsheet, because then the dispatch timestamp never enters the chain of custody and you cannot answer where a sample was on a given day.
- • Cannot defer: consent capture and versioning, kit ID scheme, sample chain-of-custody states, lab data exchange, result release gating, audit logging on sample and result mutations, data deletion capability
- • Can defer: partner and practitioner dashboards, warehouse automation and pick-pack optimisation, BI and cohort analytics, public integration APIs, subscription and re-test scheduling, multi-language content
- • Can be manual at launch but must be recorded in-system: dispatch confirmation, exception handling for failed samples, refund and resample decisions
Firestore versus Postgres for sample records with audit requirements
We use Firestore for customer-facing state and Postgres for sample and result records that carry audit obligations. The deciding factor is not scale or cost, it is that regulated records need multi-record transactional integrity, immutable append-only history, and queries that reason across time ranges and status transitions. Postgres does all three natively.
Firestore is genuinely good at the customer portal: real-time subscription to order and result status, straightforward security rules scoped to a user, low operational overhead. Where it becomes awkward is the audit trail. You end up hand-rolling an event collection, writing your own compare logic to produce before-and-after diffs, and accepting that a document write and its audit entry are two operations you have to keep consistent yourself. In Postgres, a history table with a trigger gives you that for free, and the history table is the source of truth for what happened rather than a best-effort log.
The second Postgres argument is reconciliation queries. Questions like show every sample dispatched more than 21 days ago with no result, grouped by courier and lab batch, are one query in SQL and an export-and-process job in Firestore. In a diagnostics business you ask that kind of question constantly, because it is how you find the customers who are about to complain. Our practical split: Firestore for portal reads and real-time UI state, Postgres for the sample lifecycle, results, consent records, and audit history, with a one-way sync into the customer-facing layer.
The real cost of retrofitting audit trails and GDPR deletion
Retrofitting an audit trail is expensive because the missing data cannot be regenerated, and retrofitting deletion is expensive because personal data spreads into places nobody documented: analytics events, email service providers, support tickets, PDF result files in object storage, exported CSVs, and database backups. Designing both in at schema time costs days. Retrofitting costs weeks and leaves gaps.
The deletion problem in diagnostics has a specific shape, because you usually cannot delete everything. Laboratory and medical records often carry statutory retention periods that outlive a customer's right to erasure of their marketing profile. So deletion is not a DELETE statement, it is a policy: identify the fields that constitute personal data, sever the link between person and sample, retain the de-identified sample and result record for the required period, and destroy the linking record. If your schema mixes customer identity into the sample row, that separation is a migration across live data rather than a config change.
The practical checklist we apply before any health-tech product goes live is short. Every table that holds personal data is tagged. Every external system that receives personal data is listed with an owner and a deletion mechanism. Every mutation on samples, results, consent, and release state writes an audit entry with actor, timestamp, and before-and-after values. And there is a runnable erasure procedure that has actually been executed against a test account, not a document describing one.
Key Takeaways
- • Four things must exist before the first kit ships: a printed kit ID scheme with a PII-free tube barcode, a customer-to-barcode mapping the lab never sees, a sample chain-of-custody state machine, and versioned consent captured before dispatch.
- • Assume the lab has no API. Build a validated, versioned file exchange with raw file retention, an exception queue, and a scheduled reconciliation job that catches samples dispatched but never resulted.
- • Result release is a separate state from result availability, gated by an explicit action recorded with actor and timestamp, and scoped per audience when practitioners see results before their clients.
- • Audit trails, consent versioning, the kit ID scheme, and the deletion path cannot be deferred. Partner dashboards, warehouse automation, BI, and public APIs can be.
- • Firestore fits the customer portal and real-time status; Postgres fits sample records, results, consent, and audit history where transactional integrity and reconciliation queries matter.
The decisions above come out of our GlycanAge case study, where we acted as the dedicated engineering team for six years across 10+ interconnected systems, from laboratory management and warehouse logistics to customer portals and partner dashboards.
Frequently Asked Questions
How do I choose a software agency for a health-tech or diagnostics startup?
Ask for specifics about physical-sample workflows, not just HIPAA or GDPR claims. A team that has shipped a diagnostics product can describe their kit ID scheme, how they handled a lab with no API, how result release is gated, and what their deletion procedure actually does. Credential lists are easy to write; a chain-of-custody state machine and a reconciliation job are not.
Do I need a certified LIMS, or can we build our own lab management system?
It depends on what the lab does with it. If the lab is a partner running its own accredited processes, you integrate with whatever they have rather than replacing it. If you operate the lab yourself, building internal sample tracking around an accredited process is common, but the accreditation scope and validation requirements should be settled with your quality lead before any code is written.
How long does it take to build the first version of a diagnostics platform?
The must-have layer described here, order capture, kit registration, chain of custody, lab exchange, consent, and gated result release, is typically a few months of focused work rather than a few weeks, and the timeline is usually driven by lab integration and regulatory review rather than frontend build. Deferring dashboards, BI, and warehouse automation is what keeps that timeline realistic.
Can we use Firebase for a regulated health product?
Yes for parts of it. Firebase works well for authentication, customer portal state, and real-time status updates, provided you configure data residency, disable unnecessary telemetry, and keep the records that carry audit and retention obligations in a system that gives you transactional history. Most regulated products we have worked on end up with a hybrid: Firebase or Firestore at the edge, a relational store for the regulated core.
What is the difference between pseudonymised and anonymised sample data?
Pseudonymised data can still be re-linked to a person through a separate key, so it remains personal data under GDPR and stays in scope for access and erasure requests. Anonymised data cannot be re-linked by any reasonable means and falls out of scope. In diagnostics, the lab usually holds pseudonymised data, and erasure typically means destroying the linking key rather than deleting the sample record itself.
Sources
Written by
Filip Lauc
CEO, Jaspero
Filip Lauc is the CEO of Jaspero, a software development agency based in Osijek, Croatia. A full-stack JavaScript developer with over a decade of experience across Angular, Svelte, and Node.js, he leads Jaspero's work as a long-term embedded engineering partner for clients like GlycanAge, where his team has served as the dedicated engineering team for six years.
Let's Build Together
Your vision,
our expertise.
From AI integration to full-stack development, we turn ambitious ideas into products that perform.