# Monitoraggio remoto dei pazienti con FHIR

> Dalle letture della pressione sanguigna a domicilio agli avvisi: Osservazioni del dispositivo, webhook firmati, una regola idempotente e cosa rimane al di fuori del livello dati. Codice testato.

Source: https://developers.anpheros.com/it/guides/remote-patient-monitoring-fhir

**Il monitoraggio remoto dei pazienti (RPM) raccoglie le misurazioni che un paziente effettua a casa — pressione sanguigna, peso, glucosio, saturazione di ossigeno — e consente a un team di assistenza di visualizzarle e agire su di esse tra una visita e l'altra.** La parte relativa ai dati prevede quattro passaggi: inserire ogni lettura nel record del paziente come Osservazione codificata e attribuita al dispositivo; reagire all'arrivo di una nuova lettura; decidere con una regola chiara se necessita di attenzione; e mantenere un registro di ciò che il team ha fatto. Questa pagina costruisce tale pipeline su HL7 FHIR R4 con i webhook Anpheros e l'SDK TypeScript, con codice eseguito sulla piattaforma, ed elenca cosa rimane al di fuori del livello dati.

## La pipeline

```
 cuff, scale, glucose meter, pulse oximeter
        │ (Bluetooth / vendor app / Apple Health / Health Connect)
        ▼
 patient's phone app ──► your backend ──► FHIR Observation (author: device) in the patient's record
                                                     │ webhook: resource.created (signed)
                                                     ▼
                                     your monitoring service: rule → alert → care team
                                                     │
                                     note, call, CarePlan change, next appointment
```

Tre scelte decidono se questo funziona in pratica:

- **Una lettura, una Observation.** Ogni lettura del bracciale è una Observation con LOINC 85354-9 e due componenti (8480-6 sistolica, 8462-4 diastolica), l'ora della misurazione e `author_type: device`. A differenza dei riepiloghi giornalieri dei dispositivi indossabili, le letture RPM sono misurazioni individuali che un clinico può esaminare una per una.
- **Reagire agli eventi, non a un timer.** Un webhook per ogni nuova Observation consente all'algoritmo di essere eseguito secondi dopo l'arrivo della lettura.
- **Regole su più letture.** Una singola lettura elevata è spesso rumore; la maggior parte dei protocolli esamina una serie. L'algoritmo seguente richiede tre letture consecutive a o sopra 140/90. Tale soglia è un esempio, non un consiglio clinico: il team di assistenza imposta l'algoritmo per ciascun paziente.

## Scrittura delle letture dal dispositivo

L'app del telefono (o il cloud del produttore del dispositivo, tramite il tuo backend) scrive ogni lettura:

```ts
await anpheros.observations.create(patientId, {
  code: '85354-9', category: 'vital-signs', effective_at: '2026-10-13T07:15:00-04:00', author_type: 'device',
  components: [{ code: '8480-6', value: 152, unit: 'mm[Hg]' }, { code: '8462-4', value: 95, unit: 'mm[Hg]' }],
}, { source_system: 'bp-cuff-app' });
```

Se le letture provengono da Apple Health o Health Connect anziché direttamente dal dispositivo, leggile sul telefono come descritto in [Dati indossabili in FHIR](https://developers.anpheros.com/it/guides/wearable-data-fhir), ma mantieni le singole letture della pressione sanguigna come singole Observations anziché medie giornaliere.

## Reagire a nuove letture

Registra un endpoint webhook una sola volta (`POST /v1/webhooks` con `events: ["resource.created"]`); la risposta conterrà il segreto di firma. Esegui quindi un piccolo servizio che verifichi ogni consegna e valuti la regola:

```ts
import { createServer } from 'node:http';
import { Anpheros, apiKey, verifyWebhookSignature } from '@anpheros/sdk';

const anpheros = new Anpheros({ auth: apiKey(process.env.ANPHEROS_KEY!) });
const SECRET = process.env.WEBHOOK_SECRET!;
const seen = new Set<string>();                       // deliveries are at-least-once: de-duplicate by event id
const alerted = new Set<string>();                    // one alert per newest reading, however many events arrive

// Rule: the three most recent home readings all at or above 140/90 → tell the care team once
async function checkBloodPressure(patientId: string, observationId: string) {
  const obs = await anpheros.observations.get(observationId);
  if (obs.code !== '85354-9') return;                  // only blood pressure readings trigger the rule
  const { data } = await anpheros.observations.list(patientId, { code: '85354-9', limit: 3 });   // newest first
  const value = (o: typeof obs, code: string) => o.components.find(c => c.code === code)?.value ?? 0;
  const allHigh = data.length === 3 && data.every(o => value(o, '8480-6') >= 140 || value(o, '8462-4') >= 90);
  if (!allHigh || alerted.has(data[0].id)) return;
  alerted.add(data[0].id);
  console.log(`ALERT patient ${patientId}: last 3 readings ≥ 140/90 →`,
    data.map(o => `${value(o, '8480-6')}/${value(o, '8462-4')}`).join(', '));   // in production: notify the care team
}

createServer(async (req, res) => {
  const chunks: Buffer[] = [];
  for await (const c of req) chunks.push(c as Buffer);
  const body = Buffer.concat(chunks).toString('utf8');
  const ok = await verifyWebhookSignature({ secret: SECRET, header: req.headers['anpheros-signature'] as string, body });
  if (!ok) { res.writeHead(400).end(); return; }       // not from Anpheros, or too old
  res.writeHead(204).end();                            // answer fast; do the work after
  const event = JSON.parse(body);
  if (seen.has(event.id)) return;
  seen.add(event.id);
  const d = event.data;
  if (event.type === 'resource.created' && d.resource_type === 'Observation') await checkBloodPressure(d.patient, d.id);
}).listen(8799);
```

Come abbiamo testato: quattro letture mattutine (136/86, 144/92, 149/94, 152/95) sono state scritte su un paziente sintetico in un'istanza locale della piattaforma, e la piattaforma ha prodotto un evento `resource.created` firmato per ogni lettura. Tali eventi, firmati con il codice di firma della piattaforma stessa, sono stati inviati al servizio sopra menzionato insieme a due duplicati e una richiesta firmata con un segreto errato. Il risultato: la firma errata ha ricevuto `400`, i duplicati sono stati ignorati e il servizio ha generato esattamente un alert — `152/95, 149/94, 144/92` — non uno per evento.

In produzione, conserva `seen` e `alerted` in un database anziché in memoria, in modo che un riavvio non ripeta gli alert.

**Ricevere webhook durante lo sviluppo.** Anpheros accetta e consegna solo a endpoint HTTPS pubblici: un indirizzo `localhost` o privato viene rifiutato al momento della registrazione (`400`, campo `url`), anche nella sandbox, e ogni consegna ricontrolla l'indirizzo. Per ricevere eventi sul tuo laptop, esponi il servizio tramite un tunnel HTTPS pubblico e registra l'indirizzo del tunnel. Vedi [Webhooks](https://developers.anpheros.com/it/guides/webhooks).

## Cosa dovrebbe mostrare il record in seguito

L'allerta stessa risiede nel tuo servizio di monitoraggio, ma il record dovrebbe mostrare cosa ne è derivato, in modo che il prossimo clinico e il paziente vedano l'intera storia:

- le letture, ciascuna contrassegnata come dati del dispositivo con il suo sistema di origine ([provenance](https://developers.anpheros.com/it/guides/medical-data-provenance));
- un `CarePlan` con il piano di monitoraggio (cosa viene misurato, con quale frequenza, l'obiettivo);
- un `Encounter` (classe `VR` per un contatto remoto) quando il team chiama il paziente, e qualsiasi modifica della medicazione come un `MedicationStatement`.

Anpheros memorizza queste risorse; non dispone di una risorsa di allerta o di attività propria (`Flag`, `Task` e `Communication` non sono tra i suoi tipi di risorsa), quindi le code di allerta e l'instradamento on-call appartengono al tuo servizio.

## Fatturazione, regolamentazione e sicurezza

I programmi RPM dipendono spesso da regole di rimborso — negli Stati Uniti, Medicare paga per il monitoraggio fisiologico remoto in base a specifici codici CPT con un numero minimo di giorni con dati e tempo dedicato dal team di assistenza. Tali regole cambiano e non sono qualcosa che una piattaforma dati può certificare; verificare le attuali regole CMS e conservare le prove (le letture e il tempo del team) nel proprio sistema. Il software che interpreta le letture per guidare la diagnosi o il trattamento può essere regolamentato come dispositivo medico. Mantenere le soglie nelle mani dei clinici e registrare ogni allarme e risposta.

## Dove si colloca Anpheros

Anpheros fornisce il record (FHIR R4 Observations con provenance, CarePlan, Encounter), webhook firmati con tentativi di retry, consenso se l'app di un'altra organizzazione necessita di leggere le letture, e un log degli accessi che il paziente può visualizzare. Non si connette ai fornitori di dispositivi, non decide cosa è anormale, non invia avvisi né gestisce la fatturazione.

## Domande frequenti

### Quale risorsa FHIR memorizza una lettura della pressione sanguigna domiciliare?
Un Observation con LOINC 85354-9 (pannello pressione sanguigna) e due componenti, 8480-6 (sistolica) e 8462-4 (diastolica), ciascuno un `valueQuantity` in `mm[Hg]`, con l'ora della misurazione e il dispositivo come autore.

### I dati RPM dovrebbero essere medie giornaliere o letture individuali?
Letture individuali per misurazioni cliniche come pressione sanguigna, peso o glucosio, poiché i medici le esaminano e le contano. I riepiloghi giornalieri sono adatti per dati indossabili ad alta frequenza come frequenza cardiaca o passi.

### Come posso attivare un avviso quando arriva una nuova lettura?
Iscriviti ai webhook `resource.created`, verifica la firma, recupera il nuovo Observation e valuta la tua regola sulla serie recente. Le consegne possono ripetersi, quindi deduplica per ID evento e rendi l'avviso idempotente.

### Anpheros può inviare avvisi ai medici?
No. Notifica il tuo servizio tramite webhook; chi viene avvisato, come e quando viene deciso nel tuo sistema.

## Correlati

- [Dati indossabili in FHIR](https://developers.anpheros.com/it/guides/wearable-data-fhir)
- [Cura virtuale e medici AI: i dati di cui hanno bisogno](https://developers.anpheros.com/it/guides/virtual-care-ai-data)
- [Webhook](https://developers.anpheros.com/it/guides/webhooks)
- [Provenienza dei dati sanitari spiegata](https://developers.anpheros.com/it/guides/medical-data-provenance)
- [Integrazioni sanitarie](https://developers.anpheros.com/it/guides/healthcare-integrations)
