Skip to main

Case study · HealthTech · Diagnostics

Unilab — multi-city lab patient platform

Published · Updated · By YuSMP Group Engineering

How we shipped a production diagnostics patient platform — native iOS and Android apps, a web personal cabinet, and the adapter glue into legacy scheduling and accounting systems — built on Symfony with reliable push pipelines on APNs and FCM, a 2,500-item test catalog, and a privacy posture aligned with GDPR for the European Union and CCPA for the United States from day one.

IndustryHealthTech · Diagnostics
Project year2024
EngagementFixed price + support
Unilab — patient appointment booking, digital lab results, US and EU healthcare platform

The brief — a lab network that needed a patient surface

Unilab's administrative staff were manually handling appointment requests, inbound calls, patient data entry, and emailing test results across a network operating in more than forty cities. The existing scheduling and accounting backends were workhorses, but they had been built years before mobile traffic was a serious load class and did not expose any customer-facing surface a patient could reach from a phone. The lab needed a unified patient platform — registration and personal cabinet, online appointment booking, digital results, a searchable catalog of 2,500-plus tests, an interactive map of offices, and push reminders — that integrated with the existing scheduling and accounting systems instead of replacing them. The platform also had to hold up under healthcare privacy expectations in the United States and the European Union: GDPR for European patients, CCPA for California patients, HIPAA-capable architecture for any future US-launch scenarios. We built the platform as a Symfony backend with adapter services into the legacy systems, paired with native iOS (Swift) and Android (Kotlin) patient clients and a React web personal cabinet. The result is a production diagnostics platform that scales across cities, removes the manual administrative tax, and is positioned for compliant operation across the US and EU.

Project highlights

Native Swift iOS patient app Native Kotlin Android patient app React web personal cabinet Symfony backend + adapters APNs + FCM push pipelines 2,500+ test catalog Scheduling-system integration Multi-city ready · US & EU

By the numbers

A snapshot of what the Unilab build delivered across iOS, Android, web, and a Symfony backend wired into legacy scheduling and accounting systems.

3patient surfaces — native iOS, native Android, and a React web personal cabinet
2,500+test items in the catalog with structured search, filtering, and per-city availability
2legacy adapters — one to scheduling, one to accounting — keep operations consistent
2push pipelines — Apple Push Notification service and Firebase Cloud Messaging in parallel
40+cities supported as first-class tenants in the platform's data model
14–22 wktypical delivery window for a comparable lab patient MVP with integrations
Unilab patient personal cabinet — native iOS and Android, US and EU healthcare patient platform

Why native iOS and Android over Flutter or a WordPress portal

The platform decision dominates the reliability story of a healthcare patient app. We chose native Swift (iOS) and Kotlin (Android) over a Flutter MVP and over a WordPress patient-portal plugin because the trade-offs line up cleanly with what a multi-city lab actually needs. WordPress portals are appealing on a sales call but fall over fast under the load profile of a lab — appointment-window mutations, accounting reconciliations, push delivery at result-ready time — and pin the operator to a plugin ecosystem that no healthcare auditor takes seriously. Flutter is excellent for forms-heavy apps but adds a bridge between Dart and the platform push pipelines and biometric APIs that result-ready notifications cannot afford to be noisy about.

The build leans on Apple Push Notification service on iOS, Firebase Cloud Messaging on Android, and the Symfony framework on the backend — proven primitives that give us deterministic push behavior, predictable background sync semantics, and a backend layer that healthcare operators in the US and EU recognize and trust.

Native iOS + Android vs Flutter vs WordPress patient portal — at a glance
Dimension Native iOS + Android (Unilab) Flutter WordPress portal
Push reliabilityDirect APNs / FCM; deterministic deliveryBridge to platform pipelines; rare race conditionsWeb push only; weak on iOS
Scheduling adapter fitClean REST surface from Symfony adapterSame backend reachable; identical fitPlugin-bound; rigid mapping
Multi-city scalingTenanted data model; configuration-only city addSame; UI parity strongNetwork of sites or multi-site WP — operationally heavy
Accounting integration latencyAdapter service caches reads; sub-second UISame backend; identical latencySynchronous plugin calls; user-visible waits
Biometric & Face IDNative LocalAuthentication / BiometricPromptPlugin bridge; usually fineNot available outside native wrapper
App Store review fitFirst-class — healthcare entitlements cleanFirst-class; same review pathOften rejected as "web wrapper"
Audit posture (US + EU)Operator-owned event store, immutableIdentical backend guaranteesPlugin DB; weak audit story

References: Apple Push Notification service documentation, Firebase Cloud Messaging guide, Symfony framework documentation.

Unilab appointment booking flow — Swift / SwiftUI on iOS, scheduling-system adapter, multi-city office map

iOS build — Swift, SwiftUI, and the appointment booking flow

The iOS client is built in Swift with SwiftUI for the UI layer and a clean MVVM split that keeps the appointment booking flow readable for the next engineer who has to touch it. The booking flow is the spine of the patient experience: a patient opens the app, browses tests, picks a date, time, and office, and confirms — with the adapter service translating the request into the legacy scheduling system's protocol behind the scenes. The interactive office map is a separate flow with a MapKit-backed view and city-aware filtering, so a patient living in one city does not have to wade through offices in another to find a walk-in slot.

Push notifications are wired through APNs and segmented by intent — appointment reminders, result-ready notifications, and promotional pushes each live in their own category so users can manage them independently. Background fetch keeps the personal cabinet warm so a patient who opens the app at 7 AM sees today's appointment without waiting on a network round-trip. The end-to-end iOS surface is delivered as part of our mobile app development practice, with shared design tokens between iOS and Android so the patient experience reads as one product across both stores.

Unilab digital test results — Kotlin Android, secure result delivery, 2,500-item test catalog

Android build — Kotlin, Jetpack Compose, and digital test results

The Android client is written in Kotlin with Jetpack Compose for the UI and a foreground service for result-ready delivery on Samsung, Xiaomi, OnePlus, and Pixel device families, where aggressive battery optimizers terminate background services without warning. Results land as encrypted blobs over an HTTPS pull triggered by the FCM push, never inside the push payload itself, and a BiometricPrompt step gates access so a phone left on a café table does not surface a patient's blood panel to a stranger. WorkManager handles non-urgent operations — catalog updates, office-map refreshes, telemetry flush — with backoff semantics that respect Doze mode across Android 10 through Android 14.

The 2,500-item test catalog is where the Android client earns its keep. Structured search across categories, sub-categories, and free-text terms is served by a Symfony-backed search index, with city-aware availability so a patient in one city never sees a test that's not offered there. Per-test details include preparation instructions, turnaround times, and pricing — the same fields the legacy accounting system already maintains, exposed through the accounting adapter so the source of truth remains the operator's accounting database. The same engineering team carries iOS and Android in lockstep as part of our iOS and Android engineering practice.

Unilab scheduling and accounting adapter services — Symfony backend, US and EU healthcare compliance posture

Scheduling adapter, accounting adapter, and audit-ready posture

The scheduling and accounting adapters carry the integration weight of the platform. Each is a dedicated Symfony module that sits between the patient clients and the corresponding legacy system, translating mobile-shaped requests into the native protocol of the legacy backend and absorbing back-pressure when the legacy system is slow. The scheduling adapter manages connection pooling, caches non-mutating reads in Redis, and writes an audit trail of every appointment mutation so the operator can reconstruct activity per regulator request. The accounting adapter does the equivalent for pricing and invoice data, keeping the accounting database as the single source of truth and exposing a clean REST surface to the mobile clients without exposing the legacy system to the public internet.

Patient data lives behind role-based access control and is encrypted at rest with key rotation. The posture is built to align with GDPR obligations for patients in the European Union and CCPA / CPRA obligations for patients in California and the broader United States, with a HIPAA-capable architecture ready to scaffold a Business Associate Agreement when a US-launch scenario calls for one. Every result delivery, every appointment mutation, and every accounting reconciliation writes to an immutable audit log that survives the next regulator audit as a documentation exercise rather than an archaeological dig.

Compliance posture: GDPR-aligned · ISO 27001 ready · SOC 2 Type II in progress · HIPAA-capable · CCPA-acknowledged.

Delivery methodology

A five-phase build that took Unilab from operator pain points to production across iOS, Android, web, and the integration adapters.

Phase 1

Discovery & requirements

Patient journey mapping (call-and-paper baseline), legacy-system protocol survey, multi-city tenancy model, US and EU healthcare-privacy review (GDPR, CCPA, HIPAA-capable scaffolding).

Phase 2

Backend & adapter design

Symfony backend skeleton, scheduling-system adapter spec, accounting-system adapter spec, REST surface for mobile clients, immutable audit-log schema, role-based access control.

Phase 3

Platform builds

Native Swift / SwiftUI iOS client, native Kotlin / Jetpack Compose Android client, React web personal cabinet, 2,500-item catalog with structured search, MapKit office finder.

Phase 4

Healthcare hardening

Push pipelines on APNs and FCM, encrypted result delivery with biometric gating, audit-log testing, role-permission review, multi-city load test at projected patient volume.

Phase 5

Launch & telemetry

App Store + Google Play submission across US and EU storefronts, per-city rollout choreography, on-call runbooks for the adapter services, post-launch reconciliation with accounting.

Accounting integration, billing reconciliation, and the operator handoff

Unilab's accounting backend was the workhorse of the existing operation, and the patient platform was built to amplify it rather than replace it. The accounting adapter sits between the patient clients and the accounting database, translating mobile requests into the accounting system's native protocol while writing every transaction to an immutable reconciliation log. Pricing for the 2,500-item catalog is owned by the accounting system; the adapter caches reads in Redis with a short TTL so the patient app shows fresh prices without hammering the legacy database. Invoice generation runs on the accounting side; the adapter only exposes a read-only view so a patient can pull a receipt without ever touching the operator's bookkeeping records. The subsystem was built with operator handoff in mind: a clinic administrator opens the operator console, sees the day's appointments per city, and can intervene — reschedule, refund, contact patient — without ever leaving the platform. Cross-city operators can scope their view by region, which is how a single administrator covers operations in multiple cities during quiet shifts without losing the per-city audit trail.

Launching across the United States and the European Union

The Unilab platform was architected for healthcare operators serving patients across the United States and the European Union. The English-language build serves patients in California, New York, Texas, Florida, and Washington in the US, and patients in the Netherlands, Germany, France, Ireland, and Sweden in the EU, without a separate codebase per region. Consent flows are region-aware at the client layer: patients in the EU and EEA receive a GDPR-style granular consent screen with separate toggles for result-delivery channels and optional product analytics; patients in California receive a CCPA-style "Do Not Sell or Share My Personal Information" disclosure in the same flow. Data-handling practices are aligned with GDPR for European patients and with the US state-privacy patchwork — CCPA / CPRA (California), VCDPA (Virginia), CPA (Colorado), CTDPA (Connecticut), UCPA (Utah), TDPSA (Texas), and Oregon CPA. The HIPAA-capable architecture provides scaffolding for a Business Associate Agreement scenario, even though HIPAA applies only when the operator is a covered entity under US law.

Backend deployment runs across EU and US regions in parallel — Netherlands, Germany, France, Sweden, and Ireland for EU coverage; US East and US West for North America — with Symfony services and PostgreSQL instances provisioned identically through Terraform. The patient-data store and the audit log can be pinned to either US or EU regions for future data-residency commitments, and the adapter services are stateless so they can be scaled independently per region. Both the App Store age rating and the Google Play content rating were calibrated for a healthcare app, and the in-app privacy policy was drafted to document exactly the architecture above, citing GDPR obligations and California CCPA obligations directly. The engineering team behind the build runs a CET workday with East-Coast US overlap (9 AM–1 PM ET) for stand-ups, store-review choreography, and on-call response.

Tech stack and roadmap

Swift SwiftUI MapKit LocalAuthentication Kotlin Jetpack Compose BiometricPrompt React PHP Symfony PostgreSQL Redis APNs Firebase Cloud Messaging REST API Docker Terraform Prometheus Grafana

The active custom software development roadmap for Unilab includes a telehealth video-consultation tier, deeper integration with the operator's accounting system for direct insurance-claim handoff, a per-physician portal for partner clinics, and a structured-results JSON-LD layer so patient results render cleanly in third-party health records. A B2B tier with bring-your-own-domain, team management, and SSO is planned for US and EU corporate-health programs. Infrastructure plans include further per-city sharding, an internal continuous-verification harness for the audit-log invariants, and a future independent readiness assessment scaffolded into the cloud & DevOps roadmap.

Build a healthcare patient platform like this — talk to us

If you are planning a diagnostics patient platform, a multi-city healthcare app, or any mobile product where the integration story with legacy scheduling and accounting backends has to hold up under a regulator review for audiences in the US and EU, we have shipped this stack end-to-end and can compress the build timeline meaningfully. The live iOS client is available at the Apple App Store on iOS and Android, and the engineering team behind it sits inside YuSMP Group. We work fixed-price for well-scoped MVPs and on dedicated development teams for ongoing delivery, with a CET workday and a guaranteed East-Coast US overlap (9 AM–1 PM ET) window for stand-ups, demos, and incident response.

Book a discovery call See mobile development services

Frequently asked questions

How much does it cost to build a lab patient app on iOS and Android with scheduling integration?

A focused MVP covering native iOS and Android patient clients, a web personal cabinet, appointment booking, digital test results, and a scheduling-system adapter typically costs $160k–$320k. Adding a 2,500-item test catalog with structured search, an interactive office map, push notifications, accounting-system integration, multi-city support, and audit-ready healthcare logging brings a full platform to $360k–$700k. The dominant cost drivers are the legacy scheduling-system adapter, the accounting integration, and the platform-specific push pipelines on Apple Push Notification service and Firebase Cloud Messaging.

Why native iOS and Android over Flutter for a healthcare patient app?

Healthcare patient apps depend on platform-specific push reliability, background fetch behavior, and biometric-authentication primitives that mature faster on native than on Flutter wrappers. Native Kotlin and Swift expose APNs and FCM, Face ID and biometric prompts, and background URL-session and WorkManager primitives directly, so appointment reminders, result-ready notifications, and silent refreshes land predictably across Samsung, Xiaomi, OnePlus, Pixel, and iPhone. Flutter is excellent for forms-heavy apps but adds a bridge between Dart and platform push and biometric layers that healthcare apps cannot afford to be noisy about.

How do you integrate a patient app with a legacy lab scheduling system?

Most lab scheduling systems are not internet-facing and were not designed for mobile traffic. The integration sits behind a dedicated adapter service — a Symfony module that translates patient-app requests into the scheduling system's native protocol, manages connection pooling, and absorbs back-pressure when the legacy system is slow. The adapter caches non-mutating reads in Redis, exposes a clean REST surface to the mobile clients, and writes an audit trail of every appointment mutation so the operator can reconstruct activity across US and EU compliance audits.

How do you scale a lab patient platform to dozens of cities?

Multi-city scaling is a data-model problem before it is an infrastructure problem. Offices, scheduling windows, test menus, and pricing all live as first-class tenants of the platform — each city is configurable independently, and the patient app reads only the catalog and the office map relevant to the user's location. The backend runs stateless workers behind a city-aware router, so adding a new city is a configuration change against the tenant store rather than a code release, and Symfony's caching layer prevents catalog reads from hot-spotting any single database.

How long does it take to ship a lab patient platform with iOS, Android, and web?

A focused MVP with native iOS and Android clients, a web personal cabinet, appointment booking, digital results, and a scheduling-system adapter typically takes 14–22 weeks. Adding a 2,500-item test catalog, an interactive office map, push pipelines, accounting integration, and multi-city tenancy adds 8–14 weeks. The legacy-adapter work is frequently underestimated and should be budgeted at 4–6 weeks of dedicated effort, because scheduling-system protocols vary by lab network and rarely match the patient-app data model on the first pass.

Share this case

LinkedIn X

Plan a similar build

Book a discovery call