The context
Physio Xpert is a rehabilitation platform for physiotherapists, running in production at app.physio-xpert.com. The practitioner runs a clinical assessment, the platform derives medical flags from it, those flags drive the prescribed exercises, and the patient completes their sessions from a mobile app, reporting tolerance after each exercise.
I designed and built all of it solo since September 2025: the API, the practitioner back-office, the patient mobile app, the data schema, the hosting and the test suite. Three constraints explain nearly every technical decision that follows.
Clinical logic has to evolve without a redeployment. Alert criteria follow practice, not release cycles: they live as data, editable by practitioners themselves from the back-office.
This is health data. Certified hosting, encryption, explicit consent and access traceability form a regulatory frame that is set at design time, not at delivery.
One developer, over time. Every piece has to stay understandable and changeable by a single person five years from now, which rules out over-engineering as much as shortcuts.
The clinical decision chain
This is the piece to understand first: everything else in the architecture exists so that this chain stays correct, traceable and editable without a redeployment.
practitioner
Clinical assessment
An assessment whose content is configured, not coded.
platform
Decision engine
Answers are matched against the clinical criteria in force.
platform
Medical flags
Red flags (contraindication) and yellow flags (caution).
platform
Exercise prescription
Flags filter and weight the proposed programme.
patient
Guided session
The session runs on mobile, with tolerance feedback.
Tolerance feedback loops back into progression: the next session is stepped up, held or eased. It is a loop, not a funnel: the same patient goes through this cycle at every session.
Two properties of this chain shaped the rest of the work. First, one link is configured, not coded: a practitioner can change their assessments and alert criteria without me deploying anything. Second, the output of the last link feeds back into the first: progression is not a pure function of an initial assessment, it is a state machine accumulating the patient’s history.
Where it started, and why that changed
The product did not begin on the stack it runs on today. The first version was a React + Supabase MVP: a managed database, authentication and access rules provided by the platform, and a front-end talking straight to that database. To validate the clinical decision chain with practitioners, it was the shortest path, and it did its job.
What ended that arrangement was not a technical limit, it was the regulatory frame. As soon as the platform handles real patient records, hosting has to be HDS-certified, and health data requires timestamped consent, explicit retention and a complete access log. Those requirements belong to the server answering every request, not to a client. A front-end querying the database directly has nowhere to put them.
So the migration was not a code move, it was a complete rewrite of the application engine. Everything that lived in Supabase, the schema, the access rules and the clinical decision logic, was rewritten behind a Java / Spring Boot API on a PostgreSQL hosted at Scalingo, the single entry point for both clients. What stayed is the interface: the practitioner back-office is still React, and adding the patient mobile app extended the front-end rather than replacing it.
Carrying out that switch solo, on a product already in use, was the most instructive part of the project. It also explains the shape of the architecture today: if both interfaces only ever talk to the API, it is because the opposite was tried and could not hold up on health data.
The technical choices
API
Java and Spring Boot
End-to-end strong typing and an ecosystem whose maintenance and documentation will still be there in ten years: two properties that matter more than concision on a health product.
Boundaries
Modular monolith, a single process
Every business module owns a boundary, enforced at build time: a forbidden dependency breaks compilation instead of going to review. The isolation of microservices, without their operational cost for a team of one.
Clinical logic
Configured, not coded
Assessments and alert criteria are versioned data, edited from the back-office and effective immediately. The product stops depending on my release cycles.
Data hosting
Off Supabase, database behind the API
The MVP queried Supabase from the front-end. Timestamped consent, retention and an access log belong server-side: HDS compliance forced the schema and the access rules back behind the API.
Mobile
React Native and Expo
The patient app displays exercises and collects tolerance feedback: nothing that demands native. One codebase for iOS and Android halves the surface to maintain.
The architecture that follows
All 310 API routes live under /api/v1. The back-office and the mobile app
update at different rhythms, and an app installed on a phone does not redeploy
with a git push: API versioning is not a theoretical precaution here.
What the test suite covers
Working solo changes the method: with no reviewer, the only thing that can contradict a line of reasoning is a test. Coverage is therefore not spread evenly: it is concentrated where a silent mistake would have clinical or regulatory consequences.
Progression and training load
The most sensitive piece: it decides whether a patient steps up or eases off. It is locked down by reference corpora replayed on every run, one of them covering 19,440 transitions. Any divergence breaks the suite; the new expected behaviour has to be justified explicitly.
Clinical criteria evaluation
Every comparison operator and every combination of answers has to produce the expected flag, including degraded cases: a missing answer, an out-of-range value, a criterion referencing a question that was removed from the assessment.
Authorisation, route by route
Authorisation is declared explicitly on each route rather than inferred from the presence of a token. One test per route checks that a practitioner unrelated to the record is refused, not merely that an authenticated user is accepted.
Persistence and migrations
Tests run against a real PostgreSQL started in a container, not an in-memory database that would accept queries production rejects. The schema is rebuilt from scratch on every run: a migration that fails to replay is caught before it ships.
GDPR lifecycle
Consent collection and withdrawal, soft deletion, effective purge once retention expires, completeness of the access log. These are verifiable requirements, so they are verified.
Back-office journeys
In a real browser: login, record creation, running an assessment, reading the flags it raised, prescription. The full journey, not isolated screens.
Module boundaries
Allowed dependencies between business modules are declared and enforced at compilation. A shortcut taken on a Friday evening does not compile.
The volume is not the argument, quotable as it is: 4,658 tests on the API, whose actual execution I verified rather than just counting. The argument is that none of these areas can change behaviour silently.
What health data demands
Compliance is not a layer added before going live, it is a set of constraints written into the earliest migrations. Consent is explicit, timestamped data rather than a ticked box; deletion is soft, with a 30-day retention window; every read of a patient record is logged. These requirements belong in the schema because an audit log added afterwards leaves a historical gap nothing can fill. Hosting follows the same logic: the platform runs on Scalingo, HDS-certified, in a French region. A certification is a legal prerequisite, settled before it is an infrastructure choice.
The same principle applies to external dependencies. A monitoring tool will happily ship a name or a clinical answer inside an error context, so sensitive data is scrubbed before anything is sent, at the source rather than by filtering downstream.
Where the product stands
The platform is in production and still evolving: a 310-route API covered by 4,658 tests, a practitioner back-office, a patient mobile app on iOS and Android, and hosting on Scalingo, HDS-certified, in France, all maintained by a single person.
Opening it to patients is still ahead. That is also why this page quotes no usage metric: there is none yet, and a volume number in its place would only measure what I produced.
The central bet holds up over time: practitioners evolve their assessments and alert criteria without going through me. That is exactly what the decision engine was meant to make possible.
What the client says
Brought in to develop our health application MVP (React + Supabase) and bring it into compliance, he showed remarkable technical rigour and autonomy on a demanding subject: a rehabilitation app handling health data, with every security and compliance constraint that implies. […] Nathan was a genuine build partner on this project, not merely a contractor. I recommend him without reservation.









