Delivered remotely for a business based in Brisbane, Australia. Names withheld by agreement.
Project Overview
Industry: Healthcare — clinical workforce and care-team coordination.
Type of solution: A professional network and workflow platform: a token-authenticated REST API with a documented interface and an administrative back office, plus two offline-capable native mobile applications.
Business context: A clinical service runs on people being in the right place at the right time, and the arrangements that make that happen are almost entirely informal. When a clinician cannot attend a scheduled session, they find a suitably qualified colleague themselves. When they want a second opinion, they call someone. When something urgent happens, they try to reach whoever might be free. When the encounter is over, someone has to chase them for the codes before it can be billed. All of this runs on personal phones, over channels that leave no record, and it carries patient information while doing so.
General users: Licensed clinicians across several disciplines, clinical support and assistant roles, scheduling and coding staff, platform administrators, and a separate limited population of patients.
General purpose: To turn informal clinical coordination into a system of tracked requests between verified professionals — with explicit outcomes, encrypted clinical content, and an access trail — while remaining fast enough that people use it instead of picking up the phone.
The Business Challenge
Coverage is arranged person-to-person, and leaves no record. A clinician needing cover works through their contacts until someone says yes. There is no record of who was asked, who declined, or who ultimately agreed — which matters when the question is later revisited.
Not everyone can cover everyone. Cover has to come from someone appropriately credentialled for the work. That constraint lives in people's heads, which makes it slow to apply and easy to get wrong.
Urgent situations need fan-out, not a phone call. Reaching one person at a time is the wrong shape for an urgent request. It needs to reach a whole team simultaneously, and — critically — the person who raised it needs to know who has actually accepted, not who might have seen the message.
Clinical information travels over channels that were never built for it. Patient names, reasons for consultation and clinical notes routinely move by SMS and personal messaging. That is a compliance exposure with no encryption, no access control and no audit trail.
Professional networks are built by referral, not by search. The colleague you want to invite very often does not have an account yet. If the invitation fails at that point, the network never grows.
The billing handover is a chase. Coding staff need diagnosis and procedure codes from the clinician before an encounter can be billed, and that handover happens by email, message or corridor conversation.
Connectivity in clinical settings is unreliable. Basements, theatres and older buildings all defeat mobile data. An application that only works online is an application that fails at the moment it is needed.
It has to be faster than a text message. Every one of these problems already has a working, if unsatisfactory, solution. A platform that adds friction will lose to the phone regardless of how much better its record-keeping is.
Our Approach
Model coordination as tracked requests with explicit outcomes. Every interaction in the platform — cover, consultation, urgent call-out, colleague invitation, appointment invitation, code request — is a first-class object with a named recipient, the context it needs, and an accept or decline outcome recorded against it. Nothing depends on someone remembering a conversation.
Make encryption a property of the data model, not a decision at each call site. We built encryption as a declarative model concern: a model declares which of its attributes are protected, and those attributes are encrypted on write and decrypted on read automatically. The usual failure mode for field-level encryption is that a field gets missed when the schema grows; declaring it on the model makes coverage the default rather than the exception. Uploaded file contents are encrypted the same way before storage, whichever storage backend a deployment uses.
Encrypt the professional's data as well as the patient's. Licence numbers, certifications, specialty, education, affiliations and contact details are protected at rest alongside clinical content. Professional credentials are sensitive personal data, and treating them as ordinary profile fields is a common gap.
Log reads, not only writes. The audit layer records viewing a record as a tracked event alongside creating, updating and deleting it, capturing what was accessed, by whom, and what changed. In healthcare the question asked after the fact is usually "who looked at this", and a write-only audit log cannot answer it.
Encode credentialling requirements as configuration. Roles are data rather than code, each carrying its own registration requirements — so what a given discipline must supply to join is a configuration decision, and new roles do not require a release.
Generate the routine API surface and hand-write the interesting parts. CRUD endpoints across the domain are generated from resource definitions, with an explicit exclusion list protecting the hand-written endpoints that carry real behaviour. A wide API stays consistent and documented without twenty near-identical controllers being maintained by hand.
Let invitations outrun registration. An invitation addressed to someone without an account is held against their contact details and converted into a live invitation the moment they register. The network grows by referral because referral does not hit a dead end.
Build both clients offline-first. Each native application maintains a full local mirror of the domain, so the app opens, reads and navigates without a connection and reconciles when one returns.
Delegate real-time media. Video consultation runs on a hosted communications platform with short-lived server-issued access tokens, so no media infrastructure is operated and no long-lived credential sits on a device.
The Solution
Credentialled professional profiles. Clinicians register against a defined role carrying that discipline's own requirements — licence, certification, credentials, address — with the resulting profile protected at rest.
Colleague network with deferred invitations. Clinicians invite peers, accept or decline connections, and build a working network. Invitations to people who have not yet registered are held and delivered on sign-up.
Availability publishing. Clinicians publish availability by date with multiple time spans per day, giving the network a real picture of who can be asked.
Unified schedule. Appointments and availability blocks combine into a single timeline per clinician, with conflict checking before a slot is committed.
Appointments with colleague invitations. Procedure-based and clinic-based appointments carry invited colleagues, each invitation tracked with its own accept or decline state.
Coverage requests in four modes. Cover can be requested for a single procedure, a full day, a shift or an on-call period, directed at a named clinician and linked to the appointment concerned, with the outcome notified back to the requester.
Consultation requests. A clinician invites a named peer to consult, supplying the encounter context, site, timing, reason and notes, with an explicit accept or decline.
Urgent team call-out. An urgent request is raised against a team and a site with a stated reason and broadcast to every member, with each member's acceptance or decline recorded individually so the requester knows exactly who is responding.
Teams with primary and backup roles. Teams carry ordered membership with a primary or backup designation per member, matching how clinical rotas are actually structured.
Clinical coding handover. Scheduling staff request the diagnosis and procedure codes for an encounter; the clinician returns multiple codes across both coding systems against a single request, with the completion timestamped.
Messaging and video. Group and one-to-one messaging with attachments, plus in-app video consultation on both platforms through a hosted communications service.
Notifications. In-app notification centre with viewed state and unread counts, backed by push notification delivery with per-device registration, environment separation and delivery status tracking, and SMS as an additional channel.
Offline operation. Both native applications mirror the full domain locally, so the schedule, the network and the request history are available without a connection.
Administrative back office. Full management of every domain entity behind a granular permission matrix separating view, create, update and delete rights per module, with third-party service credentials held in configuration rather than code.
Generated API documentation. The API surface is documented from annotations in the source, so the specification tracks the implementation.
Key Features
Tracked requests with explicit outcomes Cover, consultation, urgent response, colleague and appointment invitations are all objects with a named recipient and a recorded accept or decline — replacing conversations that leave no trace.
Declarative field-level encryption of clinical and professional data Models declare which attributes are protected; encryption and decryption happen transparently at the attribute layer, so coverage is complete by construction rather than by discipline.
Access-level audit logging Reads are logged alongside creates, updates and deletes, with the subject, the actor and the change recorded — so "who accessed this record" is an answerable question.
Encrypted file storage across two backends Uploaded files are encrypted before storage and addressed by opaque capability codes, with the same semantics whether a deployment stores locally or in cloud object storage.
Role-driven credentialling Each clinical role carries its own registration requirements as configuration, so what a discipline must supply to join the network is a settings decision rather than a code change.
Urgent team fan-out with individual responses An urgent request reaches an entire team at once and collects each member's response separately, so the requester sees who has actually accepted rather than who has been notified.
Deferred colleague invitations Invitations to people who have not yet registered are held against their contact details and activated on sign-up, so professional networks grow by referral without dead ends.
Availability and conflict-aware scheduling Published availability, appointments and cover arrangements resolve into one timeline per clinician, checked for conflicts before commitment.
Clinical coding handover workflow A structured request-and-return cycle for the diagnosis and procedure codes needed to bill an encounter, supporting multiple codes across both coding systems per request.
Offline-first on both native platforms Full local domain mirrors on iOS and Android keep the application usable in the connectivity conditions clinical environments actually provide.
Technical Architecture
Mobile clients. Two independent native applications — Objective-C on iOS, Java on Android — each organised as a domain-manager layer over a local persistence store, with a networking layer above it. iOS uses Core Data across a twenty-one entity model with per-entity extensions and around seventy view controllers grouped by functional area; Android uses a hand-built SQLite layer mirroring a comparable entity set with explicit indexing. Both integrate hosted video consultation, push messaging, crash reporting and platform subscription handling.
API layer. A token-authenticated REST API. Routine resource endpoints are generated from configured resource definitions — endpoint, model, eager-loaded relationships, excluded parameters — through a template, with routes registered to match. Endpoints carrying real behaviour are hand-written and protected from regeneration by an explicit exclusion list. Nearly all routes sit behind authentication middleware.
Authentication layer. JWT bearer tokens with refresh and blacklisting, adapted to authenticate two distinct user populations — clinical staff with role-based permissions, and a separate limited patient population — through one token flow, with the user type persisted alongside identity wherever records span both.
Security layer. A reusable encryption behaviour and trait binding to model attribute events, applied across every model holding clinical or professional data; an encrypted file service abstracting local and cloud storage behind one interface; and an audit-logging component recording events with polymorphic subject and actor references, serialised state and change analysis.
Notification layer. In-app notification records with viewed state and denormalised unread counts, backed by a queued push-notification pipeline — per-device registration with environment separation, queued delivery through dedicated background workers, and per-message delivery status — plus SMS as an additional channel.
Data layer. A foreign-key constrained relational schema with soft deletes throughout, covering the professional network, availability and schedule, appointments and their invitations, coverage and consultation requests, urgent call-outs and responses, teams and membership, coding requests, messaging, notifications, devices and audit activity.
Administrative layer. A back office over the full domain with a granular permission matrix separating view, create, update and delete per module, plus settings screens holding third-party service credentials in configuration.
Flow: Native iOS / Android clients with local domain mirrors → Token-authenticated REST API (generated resources + hand-written actions) → Encryption, audit and notification layers → Relational database and encrypted file storage → Queued push delivery, SMS and hosted video
Technology Stack
| Category | Technology |
|---|---|
| Backend language | PHP |
| Backend platform | Laravel-based CMS platform with custom domain plugins |
| Database | MySQL, InnoDB, foreign-key constrained with soft deletes |
| API authentication | JWT bearer tokens with refresh and blacklisting |
| API surface | Generated REST resource controllers with hand-written action endpoints |
| API documentation | OpenAPI/Swagger generated from source annotations |
| Data protection | Application-layer field encryption (AES-256-CBC) via a reusable model behaviour |
| File storage | Encrypted file service over local disk or AWS S3 (Flysystem) |
| Audit trail | Custom activity-logging component with polymorphic subject and actor |
| Messaging & video | Twilio (SMS, and video consultation on both mobile clients) |
| Cloud services | AWS (S3 object storage, SNS) |
| Push delivery | APNs and Firebase Cloud Messaging via a queued notification pipeline |
| Queueing | Database-backed queue with dedicated background workers |
| Caching / infrastructure | Redis, nginx, PHP-FPM, containerised local environment |
| iOS | Objective-C, Core Data offline store, StoreKit subscriptions, Firebase, Crashlytics |
| Android | Java, SQLite offline store, Google Play Billing and Stripe, Firebase, Crashlytics |
| Mobile media | Hosted video SDK on both platforms with server-issued access tokens |
Technical Challenges & Solutions
| Challenge | Our Approach |
|---|---|
| Clinical data must be protected at rest without every developer remembering to protect it | Encryption implemented as a declarative model concern — a model lists its protected attributes and encryption happens transparently at the attribute layer, so new fields are covered by default rather than by discipline. |
| Healthcare requires knowing who read a record, not only who changed it | An audit component that treats viewing as a tracked event alongside create, update and delete, recording the subject, the actor and the change — making access questions answerable after the fact. |
| Two distinct user populations — clinical staff with role permissions, and a separate limited population — sharing one API | A single token flow authenticating across both, with the user type persisted alongside identity wherever a record can belong to either, so notifications, messaging and device registration all resolve correctly. |
| A wide API surface that would otherwise mean twenty near-identical controllers | Routine resource endpoints generated from configured definitions through a template, with an explicit exclusion list protecting hand-written endpoints that carry real behaviour — consistency where it is routine, freedom where it is not. |
| Professional networks grow by referral, but the person being referred usually has no account | Invitations addressed to non-users are held against their contact details and converted into live invitations on registration, so referral never hits a dead end. |
| Urgent requests need to reach a whole team, and the requester needs to know who actually accepted | Fan-out to every team member with each response recorded as a separate object, so acceptance is a fact about individuals rather than an assumption about delivery. |
| Clinical environments have unreliable connectivity | Offline-first architecture on both native platforms, each maintaining a full local mirror of the domain so the application remains usable without a connection and reconciles when one returns. |
| Time-critical notifications must not be blocked by third-party delivery latency | A queued notification pipeline with per-device registration, environment separation and dedicated background workers, so delivery to push services never sits on a user-facing request. |
| Credentialling requirements differ by clinical discipline | Roles held as configuration, each carrying its own registration validation, so adding a discipline or changing what it must supply does not require a code change. |
Security & Reliability
Token-based authentication. JWT bearer tokens with refresh and explicit blacklisting on logout, covering registration, activation, password recovery and profile management flows.
Encryption at rest, applied by construction. Clinical content and professional credentials are encrypted at the application layer through a declarative model mechanism, so protection is a property of the data model rather than a decision made repeatedly at each point of use.
Encrypted file storage. Uploaded files are encrypted before being written to storage, addressed by opaque capability codes rather than predictable identifiers or paths, with identical semantics across storage backends.
Access audit trail. Reads as well as writes are recorded, with the record accessed, the person accessing it and the change captured — the audit shape healthcare access requirements actually call for.
Granular authorisation. A permission matrix separating view, create, update and delete rights per functional module, layered over role-based identity, with access additionally scoped by the professional network so clinicians without elevated privileges see only their own connections.
Explicit outcomes on every request. Cover, consultation, urgent response and invitations all carry a recorded accept or decline, so the state of any arrangement is a fact in the system rather than a recollection.
Credential separation. Third-party service credentials are held in configuration and administrative settings rather than in source.
Reliability of delivery. Notification delivery is queued with per-message status tracking, so a transient failure in an external push service is a retryable record rather than a silently lost message.
Guarded destructive operations. Data-seeding and destructive schema operations are guarded against execution in production environments.
Scalability & Performance
Offline-first clients. The largest performance decision in the product is architectural: both native applications read from a local domain mirror rather than the network, so ordinary navigation costs nothing in latency and the application is fast in exactly the conditions where the network is slowest.
Queued notification delivery. Push messages are enqueued and processed by dedicated background workers, so external delivery latency never appears in a user-facing request.
Denormalised counters. Notification badge counts are maintained on the user record rather than computed per request, and unread counts have a dedicated lightweight endpoint — both hot paths on an application opened many times a day.
Storage that scales independently. File storage is abstracted behind a single interface with a cloud object storage backend available, so media growth is decoupled from application servers.
Stateless application tier. Token authentication and externalised storage keep application instances free of local session state.
Constrained, indexed schema. A foreign-key constrained relational schema with soft deletes, mirrored on both clients with explicit index creation on the local stores.
Push over polling. Time-critical cover and urgent-response events reach clinicians by push notification and SMS rather than by client polling.
Business Outcomes
- Coverage arrangements became records rather than conversations, with the request, the recipient and the outcome all captured.
- Urgent requests reach an entire team at once, and the person who raised one can see exactly who has accepted rather than who was notified.
- Clinical information moved off personal messaging, into a channel where it is encrypted at rest and access to it is logged.
- Professional credentials are protected as sensitive data, not held as ordinary profile fields.
- Access to clinical records is answerable after the fact, because reads are audited alongside changes.
- Professional networks grow by referral without breaking, because an invitation to someone who has not yet joined survives until they do.
- The billing handover became a tracked workflow, replacing an informal chase for codes with a request that has a completion state.
- The applications work where clinicians work, because both clients operate offline and reconcile when connectivity returns.
- Credentialling requirements can change without a release, because roles and their requirements are configuration.
Why it worked
Healthcare software has a particular failure mode. The compliance requirements are visible and get built; the speed requirement is invisible and gets missed. If arranging cover through the platform takes longer than sending a text message, clinicians will send the text message — and then the platform has all the audit infrastructure and none of the data. Every design decision here was made against that constraint.
That is why encryption was built as a property of the data model rather than a series of decisions at individual call sites: it is the only version that stays complete as the schema grows, and completeness is what the compliance argument rests on. It is why reads are audited and not just writes, because the question asked after an incident is who looked, not who changed. It is why the professional's own credentials are protected alongside patient data, which is the gap most products in this space leave open. And it is why both clients were built offline-first — an expensive decision, and the correct one for buildings where mobile data does not reach.
Our team works across PHP and Laravel-based platforms, REST API design and generation, native iOS and Android development, offline-first mobile architecture, third-party communications and payment integration, and the data-protection and audit design that regulated domains require — with the judgement to know which parts of a clinical process must be modelled faithfully and which parts simply need to get out of the way.
Final Summary
Clinical coordination runs on personal phones. Cover is arranged by calling colleagues until one agrees. Consultations are requested by text. Urgent situations are handled by contacting whoever might be free. Codes for billing are chased down a corridor. All of it carries patient information, none of it leaves a record, and every part of it works well enough that nobody has replaced it.
Our team built a platform that does replace it. Clinicians register against a role that defines what their discipline must supply, build a network of verified colleagues, and publish their availability. Cover can be requested for a procedure, a day, a shift or an on-call period from a named peer, with the outcome recorded. Consultations are invitations with clinical context attached and an explicit answer. Urgent situations fan out to an entire team, and each member's acceptance or decline comes back separately, so the person who raised it knows who is actually coming. Coding requests close the loop on billing. Messaging and video keep the conversation inside the platform.
Underneath, the compliance work is structural rather than bolted on. Clinical content and professional credentials are encrypted at rest through a mechanism declared on the data model itself, so protection does not depend on anyone remembering it. Files are encrypted before storage and addressed by opaque codes. The audit trail records who viewed a record, not only who changed it. Permissions separate view, create, update and delete per module, and visibility is scoped by the professional network. And both native clients hold a full local mirror of the domain, so the platform works in the basements and older buildings where the mobile signal does not — which, for a product that has to beat a text message, is the difference between a system people use and a system people work around.