Contact
← Invariance / Portfolio
Client projectHealthcare · 2024–2025

Three extensions that gave a legacy clinical system a second language — and a spell-checker.

Dolomiti Sportclinic writes its reports in a web ERP that offers no spell-check, no translation and no dictation. Replacing it was never on the table. Instead we added three browser extensions that reach into the system the doctors already use and give them correction, translation and speech-to-text where they type.

The correction extension's popup, open on a report field

The correction extension's popup, open on a report field

The correction popup. One button proofreads the field the cursor is in; the second walks all nine sections of a structured report in sequence. The language selector only decides which rules apply — the text itself is never rewritten into another language here.

The translation extension's popup with the target language selected

The translation extension's popup with the target language selected

The translation popup. A target language is chosen once, and the translated section is appended beneath the original so the field carries both versions. Running it again replaces the previous translation instead of stacking a third copy.

The dictation extension's popup while recording

The dictation extension's popup while recording

The dictation popup. Recording happens in the browser, the transcript is cleaned up before it lands, and on a structured report the spoken text is split across the correct sections automatically.

Role
Product · Architecture · Full-stack development · Delivery
Languages
German · Italian · English
Status
In daily clinical use

Introduction

The software was not going to change. The work had to.

South Tyrolean clinicians switch between German and Italian mid-sentence and type fast between patients. Their reporting system is a long-lived web application with no text assistance of any kind, and reports go out to patients, insurers and referring physicians. Rewriting the ERP would have been a multi-year project. The workflow around it could be fixed in weeks.

150,000+

times the extensions have been used

28.7M

words processed

~10,000

hours of manual work saved

Correction

Proofreading

Fixes spelling, punctuation and light grammar in place, in whichever language the text was written — without touching the content, dates or structure. One field, or all nine report sections in sequence.

Translation

German · Italian · English

Translates a report section into the target language and appends it beneath the original, so the field carries both versions. Re-translating replaces the previous result rather than stacking a third copy.

Dictation

Speech to text

Records in the browser, transcribes, cleans up the transcript, and types it into the report. On a structured report it splits what was said across the correct sections by itself.

Demonstration

What the doctor actually sees.

A reconstruction of the correction extension against a stand-in for the clinical system, rebuilt from its own markup and styles. Press Korrigieren and watch the field — every word that changes gets its underline.

Clinical report — outpatient

AnamnesiEsame obiettivoEsami strumentaliDiagnosiTerapia

Anamnesis

78-jähriger Patien stellt sich nach einem sturz aus dem stand mit starken schmerzen in der rechten hüfte vor. Es besteht eine unfähigkeit das bein zu belasten sowie ein stechender schmerz in der leistenregion. Verdacht auf eine mediale schenkelhalsfraktur weitere diagnostik durch röntgen und ggf CT geplant.

Sample text — no patient data.

Translation

Translation that appends, not replaces.

The translation extension writes its result underneath the original behind a language marker, so the field ends up bilingual — typed in the way the clinic sees it arrive.

Clinical report — outpatient

AnamnesiEsame obiettivoEsami strumentaliDiagnosiTerapia

Anamnesis

78-jähriger Patien stellt sich nach einem sturz aus dem stand mit starken schmerzen in der rechten hüfte vor. Es besteht eine unfähigkeit das bein zu belasten sowie ein stechender schmerz in der leistenregion. Verdacht auf eine mediale schenkelhalsfraktur weitere diagnostik durch röntgen und ggf CT geplant.

Sample text — no patient data.

Technology

Proven tools, chosen as a system.

Nothing in the browser that can go stale, and the moving parts kept in services behind it.

Manifest V3 extensions

Google Chrome

The browser the clinic works in, and the extension platform the plugins are built for. Manifest V3 keeps them to narrowly scoped permissions on exactly the pages they are needed on.

Manifest V2 builds

Firefox

The second browser the suite ships for. Its extension APIs are close enough to Chrome's that one codebase serves both, with a separate manifest per build.

No framework, no build

JavaScript

The extensions are plain JavaScript with no framework and no build step — the file that ships is the file that was written. In a browser extension that is a feature: less to audit, nothing to break silently on an update.

Service language

Python

The language the backend services are written in, chosen for how directly it works with text and language models. It keeps the services small enough to read end to end.

Correction & translation API

Django

The framework serving correction and translation. It arrives with the parts a real service needs — data models, authentication, an admin surface — so effort goes into the domain rather than the scaffolding.

Dictation service

FastAPI

The framework serving dictation. It is asynchronous, which matters when requests are dominated by waiting on a model, and it derives its request validation and API documentation from the types themselves.

Language models

OpenAI

The language and speech models doing the actual work: transcription, correction and translation. They are reached over an API under a contract, so nothing depends on a model running on clinic hardware.

Reproducible runtime

Docker

The application and everything it needs are packaged into one image, so the version tested is bit-for-bit the version that runs in production. Deployment stops depending on what happens to be installed on a server.

Signed data terms

HIPAA amendment

A signed contract with the model provider covering protected health information: defined obligations, defined permitted use, defined breach handling. It is what makes sending clinical text to an external model a deliberate arrangement rather than an assumption.

No prompt storage

Zero Data Retention

The account setting under which prompts and responses are not stored by the provider after the request is answered. The passage travels, is processed, and leaves nothing behind — no training set, no log to subpoena.

Architecture

Reach into a system you are not allowed to change.

The clinical application is untouched. Everything happens in the browser, in the doctor's own session, between the moment they finish typing and the moment they click.

In the browser

Clinical ERP

Unmodified. The doctor types; the application is never touched.

Browser extension

Runs in the doctor's own session, on an explicit click.

  • Screen recognised
  • Active field resolved
Correction
Translation
Dictation

Native input event

The application updates as if a human had typed.

Off the browser

Only the selected passage crosses

Django service

Correction & translation

FastAPI service

Dictation

Language model

HIPAA amendment · zero retention

RequestProcessingResponse
  1. Recognise the screen

    The report view and the secretary view are laid out differently. The extension works out which one is open and adapts what it offers — the all-sections action simply disappears where it makes no sense.

  2. Find the right field

    A report is split across nine sections behind a tab strip. The extension resolves which tab is active and reads the field behind it; for the all-sections run it walks the tabs in order and returns the doctor to where they started.

  3. Send only the text

    The selected passage goes to a service that applies the language model and returns the corrected text — nothing else about the patient or the session travels with it.

  4. Write it back convincingly

    Setting a value on a field is not enough for a modern web framework to notice. The extension writes the text and then dispatches the same input event the browser would, so the application's own model updates as if a human had typed it.

Legal

Where the legal line sits.

These tools carry patient reports, so what may be done with that text — and by whom — is settled in writing before a single request leaves the browser.

A signed HIPAA amendment

Processing runs under a HIPAA business-associate amendment obtained for this work, rather than default consumer terms. It names what the provider may do with the text and what it may not.

Zero Data Retention

Requests are covered by a zero-retention arrangement: the text produces the answer and is not stored afterwards, and is never used to train a model.

Only the passage travels

The field's text is the whole payload. No patient identifier, record number or session context is attached to a request, so there is nothing to correlate even in transit.

Nothing is kept on our side

The services hold no database of report text. A request is processed and answered; afterwards there is nothing left to breach, subpoena or export.

The clinic decides, every time

Nothing is sent in the background. Each extension acts on an explicit click, on the one field the doctor is working in — so the decision to send clinical text stays a human one.

The clinic owns what was built

Source, builds and signing material belong to the clinic. Invariance keeps no copy of clinical content and no independent right to use it.

Result

Used every day, by people who never asked for software.

The three extensions are in daily use at the clinic. The reporting system they attach to has not been modified once — which is exactly why the project was possible at all. The same pattern applies anywhere a business is stuck with a system it cannot replace but cannot keep working in either.

Book a call