npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

aziendasanitaria-utils

v1.2.76

Published

Un utility per gestire i flussi sanitari Siciliani e non solo..

Readme

aziendasanitaria-utils

npm version license node GitHub last commit GitHub issues GitHub stars ES Modules

Libreria Node.js per la gestione dei flussi informativi sanitari della Regione Sicilia e l'integrazione con i portali istituzionali (Tessera Sanitaria, NAR/NAR2).


Indice


Installazione

npm install aziendasanitaria-utils

Requisiti: Node.js >= 14.0.0 | ES Modules ("type": "module")


Quick Start

import { flussiRegioneSicilia } from "aziendasanitaria-utils";
import { struttureDistrettiMap, distretti, comuniDistretti } from "aziendasanitaria-utils/src/config/sicilia/messina.js";

// Configurazione strutture territoriali
const strutture = new flussiRegioneSicilia.StruttureDistrettiPerProvincia(
    distretti, comuniDistretti, struttureDistrettiMap
);

// Impostazioni Flusso M
const impostazioni = new flussiRegioneSicilia.ImpostazioniFlussoM(
    "205",                          // codice ASL
    "190",                          // codice Regione
    "/path/to/input",               // cartella input
    "/path/to/output",              // cartella output
    "/path/to/FlowLook.mdb",       // database FlowLook
    strutture
);

// Elaborazione
const flussoM = new flussiRegioneSicilia.FlussoM(impostazioni);

Architettura

aziendasanitaria-utils
|
|-- Flussi Sanitari           Elaborazione file a record fisso (TXT 381 char)
|   |-- FlussoM               Prestazioni specialistiche ambulatoriali
|   |-- FlussoSIAD            Sistema Informativo Assistenza Domiciliare
|   |-- FlussoHOSPICE         Cure palliative
|   |-- FlussoARSFAR          Assistenza Residenziale Semiresidenziale
|   `-- FlussoRSA             Residenze Sanitarie Assistenziali
|
|-- Servizi Esterni           Integrazione con portali istituzionali
|   |-- Ts                    Tessera Sanitaria (HTTP headless + Puppeteer)
|   |-- Nar / Nar2            Nuova Anagrafe Regionale (Puppeteer + REST API)
|   |-- Assistiti             Gestione completa dati assistiti
|   `-- Medici                Gestione dati medici MMG/PLS
|
|-- Indicatori                Calcolo indicatori LEA (D33ZA, D30Z)
|
`-- Config                    Configurazione territoriale e credenziali

Moduli

Flussi Sanitari

FlussoM - Prestazioni Specialistiche

Il modulo principale per l'elaborazione del flusso M (prestazioni ambulatoriali).

| Funzionalita | Stato | |---|:---:| | Verifica formale record | ✅ | | Acquisizione dati da DB FlowLook | ✅ | | Unione file TXT | ✅ | | Verifica duplicati (anche milioni di record) | ✅ | | Controllo date, nomi file, distretti | ✅ | | Elaborazione informazioni finanziarie | ✅ | | Verifica strutture su portale Sogei/TS | ✅ | | Calcolo differenze e congruita TS | ✅ | | Report HTML ed Excel | ✅ | | Invio report via mail per distretto | ✅ | | Calcolo volumi | ✅ |

FlussoSIAD - Assistenza Domiciliare

| Funzionalita | Stato | |---|:---:| | Conteggio prestazioni | ✅ |

FlussoHOSPICE - Cure Palliative

| Funzionalita | Stato | |---|:---:| | Calcolo giornate di degenza | ✅ |

FlussoARSFAR - Assistenza Residenziale

| Funzionalita | Stato | |---|:---:| | Calcolo ammissioni | ✅ |

FlussoRSA - Residenze Sanitarie

| Funzionalita | Stato | |---|:---:| | Elaborazione dati RSA | ✅ |


Servizi NAR / Tessera Sanitaria

Ts - Tessera Sanitaria

Integrazione con il portale SistemaTS per la verifica e la ricerca di dati sanitari.

Modalita headless (senza browser) - usa axios + cheerio:

import { Ts } from "aziendasanitaria-utils/src/narTsServices/Ts.js";
import { ImpostazioniServiziTerzi } from "aziendasanitaria-utils/src/config/ImpostazioniServiziTerzi.js";

const config = new ImpostazioniServiziTerzi({
    ts_username: "CODICE_FISCALE",
    ts_password: "PASSWORD"
});
const ts = new Ts(config);

// Ricerca STP/ENI per codice
const risultato = await ts.ricercaStpPerCodice({
    prefisso: 'STP',       // 'STP' o 'ENI'
    codiceAsl: '205',
    suffissoCodiceStp: '0000001'
});
// => { error: false, data: { codice_stp_eni, cognome, nome, genere, ... } }

// Ricerca STP/ENI per range
const elenco = await ts.ricercaStpPerRange({
    prefisso: 'STP',
    codiceAsl: '205',
    dal: '0000000',
    al: '9999999'
});
// => { error: false, data: [{ codice_stp_eni, cognome, nome, genere, nazionalita }, ...] }

// Ricerca STP/ENI per dati anagrafici
const ricerca = await ts.ricercaStpPerDati({
    prefisso: 'STP',
    codiceAsl: '205',
    cognome: 'ROSSI',
    genere: 'M'
});

// Dettaglio da link nella lista
const dettaglio = await ts.getDettaglioStp(elenco.data[0]._detailLink);

// Parsing file forniture assistiti TS (offline, no login)
const { data, stats } = Ts.getDataFromTSFile("/path/to/file.txt");

// --- Cambio medico di base (modulo Gestione Assistiti) ---

// Aggiornamento medico: crea un nuovo periodo di assistenza per l'assistito.
// Vincolo: la data deve essere > data inizio assistenza esistente e <= oggi.
const agg = await ts.aggiornaMedicoAssistito({
    cfAssistito: 'RSSMRA80A01F158X',
    cfMedico: 'BTASLV97B46F158J',   // CF del medico (value della select)
    dataAggiornamento: null          // opzionale, default = oggi (gg/mm/aaaa)
});
// => { error: false, data: { cfAssistito, cfMedico, dataInizioValidita, codDescRegioneAsl,
//      medicoPrecedente: "NOME - CF", medicoPrecedenteCf: "CF", medicoAttuale: "NOME - CF" } }

// Rettifica medico: corregge in place l'associazione corrente (NESSUN vincolo di data).
// Utile per fixare un aggiornamento errato senza creare un nuovo periodo.
const ret = await ts.rettificaMedicoAssistito({
    cfAssistito: 'RSSMRA80A01F158X',
    cfMedico: 'PRSNNN56B22F158D'
});
// => { error: false, data: { ..., medicoPrecedente, medicoPrecedenteCf, medicoAttuale } }
// In caso di errore: { error: true, data: null, message: "<messaggio dal portale>" }

// --- Copia (PDF) della Tessera Sanitaria ---
// Scarica la copia provvisoria della tessera dato il CF dell'assistito.
const tessera = await ts.getCopiaTesseraSanitaria({
    cfAssistito: 'RSSMRA80A01F158X',
    filePath: '/tmp/tessera.pdf'    // opzionale: se valorizzato salva il PDF su disco
});
// => { error: false, data: { cfAssistito, numeroTessera, dataScadenza, stato,
//      pdf: <Buffer>, filePath? } }
// Il PDF è restituito come Buffer (utilizzabile lato server senza UI).

ts.closeHttpSession();

Note cambio medico: la tessera viene sempre impostata a CNS e la valenza TEAM "Si". Il portale richiede una doppia conferma (recap + commit), gestita internamente dalle funzioni con due POST sequenziali; il medico precedente viene sempre letto e restituito.

Modalita browser (Puppeteer) - per operazioni legacy:

const page = await ts.getWorkingPage(true); // true = visibile
// ... operazioni con Puppeteer
await ts.doLogout();

Nar2 - Nuova Anagrafe Regionale (REST API)

import { Nar2 } from "aziendasanitaria-utils/src/narTsServices/Nar2.js";

const nar2 = new Nar2(impostazioniServiziTerzi);
const token = await nar2.getToken();

// Ricerca assistiti con parametri
const assistiti = await nar2.getAssistitiFromParams({
    [Nar2.PARAMS.COGNOME]: 'ROSSI',
    [Nar2.PARAMS.NOME]: 'MARIO',
    [Nar2.PARAMS.AZIENDA]: '205'
});

// Elenco medici MMG/PLS, con dati dei rapporti individuali e degli indirizzi
const medici = await nar2.getMediciFromNar2({
    soloAttivi: true,
    aggiungiDatiRapporti: true,   // allega `rapporti` e `indirizzi` a ogni medico
    parallelsRapporti: 10         // richieste eseguite in parallelo
});

// Solo i rapporti / gli indirizzi di un medico dato il suo pf_id
const rapporti = await nar2.getRapportiMedicoFromId(5860, 'ME');
const indirizzi = await nar2.getIndirizziMedicoFromId(5860, 'ME');

// Lookup comuni (cm_id NAR2) per nome/CAP/ISTAT/catastale, con filtro esatto
// e fallback CAP generico per le città multi-CAP (98167 → 98100)
const {comune, candidati} = await nar2.getComuneNar2({cap: '98167'}); // → MESSINA (id 83)

// Aggiornamento residenza/domicilio (PUT /pazienti/{id}, dryRun default true).
// Sorgenti combinabili: daTs (entrambi dal Sistema TS), residenzaDaTs/domicilioDaTs
// (singola sezione da TS), residenza/domicilio personalizzati {via, civico, cap, comuneId|criterio}
const dry = await nar2.aggiornaIndirizziAssistito(cf, {daTs: true});            // ispeziona dry.diff/warnings
const sent = await nar2.aggiornaIndirizziAssistito(cf, {
    residenzaDaTs: true,
    domicilio: {via: 'VIA ROMA', civico: '10', cap: '98057'},                   // comune risolto dal CAP
    dryRun: false
});
// Vedi docs/CAMBIO_MEDICO_NAR2.md §5.b — la verifica indirizzi è lo step standard
// che precede il cambio medico (test interattivo: node ./test-cambio-medico.js)

// ── Inserimento nuovo assistito (fonte: Sistema TS) ──
// Vedi docs/INSERIMENTO_ASSISTITO_NAR2.md. Input minimo: solo il codice fiscale.

// Dati separati TS/NAR2 + esistenza per fonte (pre-check inserimento)
const check = await nar2.verificaAssistitoTsNar2(cf);
// → {ts: {esiste, dati, errore}, nar2: {esiste, dati, errore}, inseribileSuNar2}

// Indirizzo di residenza dal recapito dell'ULTIMA tessera sanitaria (Sistema TS,
// modulo Gestione Assistiti; REGOLA: sempre la più recente, qualunque stato)
const ts = new Ts(impostazioni);
const tessera = await ts.getIndirizzoUltimaTessera({codiceFiscale: cf});
// → {indirizzo, numero_tessera, stato, data_scadenza, regione, asl, ...}

// Orchestratore completo (Assistiti): verifica → indirizzo tessera → POST /pazienti
const assistiti = new Assistiti(configData);
const dryIns = await assistiti.inserisciNuovoAssistitoDaTs(cf);                 // dryRun default: payload+derivazioni
const ins = await assistiti.inserisciNuovoAssistitoDaTs(cf, {dryRun: false});   // creazione reale → ins.pzId
// (test interattivo: node ./test-cambio-medico.js — se il CF non esiste su NAR2
//  propone l'inserimento; modalità [V] verifica TS/NAR2, [T] recapito tessera)

Ogni rapporto è normalizzato così (include anche i rapporti non attivi; attivo è true solo se manca la data di fine):

{
    id: "75337",
    categoria: "mmg",                 // "mmg" | "pls"
    tipoRapporto: "MDB",
    descrizioneRapporto: "Medico di base",
    email: "...",
    telefoni: ["3780818127", "3403896880"],   // array, scarta i valori nulli
    dataInizio: "25/05/2026",         // dd/MM/yyyy
    dataFine: null,                   // null = rapporto attivo
    attivo: true,
    domicilio: {                      // indirizzo studio; null se NAR non fornisce il link
        comune: "MESSINA",
        provincia: "ME",
        cap: "98100",
        indirizzo: "VIA CENTONZE",
        numeroCivico: "72"
    }
}

Gli indirizzi del medico (legati al medico, non al rapporto) sono restituiti tutti in array, normalizzati così:

{
    progressivo: "1",
    descrizione: "RESIDENZA",          // può essere null
    comune: "CANICATTI'",
    provincia: "AG",
    cap: "92024",
    indirizzo: "VIA S. CORAZZINI, 9",
    numeroCivico: "1",
    dataAttivazione: "21/03/2065",     // dd/MM/yyyy
    dataDisattivazione: null,
    residenza: true,                   // true se è l'indirizzo di residenza
    telefoni: [],
    email: null
}

Assistiti - Gestione Dati Assistiti

Orchestratore che combina dati da TS, NAR e NAR2.

import { Assistiti } from "aziendasanitaria-utils/src/narTsServices/Assistiti.js";

const assistiti = new Assistiti(configServiziTerzi);
const dati = await assistiti.apriMMGAssistiti(codiceMMG, listaCF);

| Funzionalita | Stato | |---|:---:| | Verifica data decesso da TS | ✅ | | Recupero dati da NAR/NAR2 | ✅ | | Generazione documenti DOCX | ✅ | | Elaborazione batch parallela | ✅ |

Medici - Gestione Dati Medici

import { Medici } from "aziendasanitaria-utils/src/narTsServices/Medici.js";

const medici = new Medici(impostazioni, true);

| Funzionalita | Stato | |---|:---:| | Ricerca medici MMG/PLS | ✅ | | Integrazione NAR | ✅ | | Report PDF/Excel | ✅ |


Indicatori

Calcolo degli indicatori LEA (Livelli Essenziali di Assistenza).

| Indicatore | Descrizione | |---|---| | D33ZA | Identificazione anziani >75 anni con patologie specifiche (da file ARS) | | D30Z | Indicatore composito SIAD/Hospice |


Configurazione

ImpostazioniServiziTerzi

Credenziali per i servizi esterni:

const config = new ImpostazioniServiziTerzi({
    ts_username: "",    // Codice Fiscale per Tessera Sanitaria
    ts_password: "",    // Password TS
    nar_username: "",   // Username NAR
    nar_password: "",   // Password NAR
    nar2_username: "",  // Username NAR2
    nar2_password: ""   // Password NAR2
});

StruttureDistrettiPerProvincia

Configurazione territoriale con distretti, comuni e strutture sanitarie. Include configurazione preconfigurata per Messina.

import { struttureDistrettiMap, distretti, comuniDistretti } from "aziendasanitaria-utils/src/config/sicilia/messina.js";

API Reference

Exports principali

import { flussiRegioneSicilia } from "aziendasanitaria-utils";

const {
    // Flussi
    FlussoM,
    FlussoSIAD,
    FlussoHOSPICE,
    FlussoARSFAR,
    FlussoRSA,

    // Configurazione
    ImpostazioniFlussoM,
    ImpostazioniFlussoRSA,
    ImpostazioniFlussoHOSPICE,
    ImpostazioniFlussoARSFAR,
    ImpostazioniMail,
    ImpostazioniServiziTerzi,
    StruttureDistrettiPerProvincia,

    // Servizi
    Assistiti,
    Medici,
    Indicatori,

    // Dati regionali
    Messina
} = flussiRegioneSicilia;

Ts - Metodi STP/ENI (headless)

| Metodo | Parametri | Ritorno | |---|---|---| | ricercaStpPerCodice() | { prefisso, codiceAsl, suffissoCodiceStp } | { error, data, message? } | | ricercaStpPerRange() | { prefisso, codiceAsl, dal, al } | { error, data[], message? } | | ricercaStpPerDati() | { prefisso, codiceAsl, cognome, genere } | { error, data[], message? } | | getDettaglioStp() | detailLink | { error, data, message? } | | closeHttpSession() | - | void | | Ts.getDataFromTSFile() | filePath | { data[], stats } |

Campi restituiti (dettaglio singolo):

| Campo | Esempio | |---|---| | codice_stp_eni | STP1902050000001 | | cognome | ROSSI | | nome | MARIO | | genere | M | | data_nascita | 01/01/1990 | | nazionalita | ROMANIA | | indirizzo | VIA ROMA 1 | | cap | 98100 | | comune | MESSINA | | provincia | ME | | medico | BIANCHI LUIGI | | asl_ao | 205 - ASP MESSINA | | regione | Sicilia | | tipo_assistito | assistito STP | | data_inizio_assistenza | 01/01/2024 | | data_fine_assistenza | 01/07/2024 | | motivazione_fine_assistenza | FINE ASSISTENZA (DA PARTE DEL SSN) |

Campi restituiti (elenco):

| Campo | Descrizione | |---|---| | codice_stp_eni | Codice identificativo | | cognome | Cognome | | nome | Nome | | genere | M/F | | nazionalita | Nazionalita | | _detailLink | Link per getDettaglioStp() |


Struttura del Progetto

aziendasanitaria-utils/
├── index.js                         # Entry point - export principale
├── package.json
│
├── src/
│   ├── m/
│   │   ├── FlussoM.js               # Flusso M - Prestazioni specialistiche
│   │   └── DatiStruttureProgettoTs.js
│   │
│   ├── siad/
│   │   └── FlussoSIAD.js            # Flusso SIAD - Assistenza domiciliare
│   │
│   ├── hospice/
│   │   └── FlussoHOSPICE.js         # Flusso Hospice
│   │
│   ├── ars-far/
│   │   └── FlussoARSFAR.js          # Flusso ARS ex FAR
│   │
│   ├── rsa/
│   │   └── FlussoRSA.js             # Flusso RSA
│   │
│   ├── narTsServices/
│   │   ├── Ts.js                    # Tessera Sanitaria (HTTP + Puppeteer)
│   │   ├── Nar.js                   # NAR legacy (Puppeteer)
│   │   ├── Nar2.js                  # NAR2 REST API
│   │   ├── Assistiti.js             # Gestione assistiti
│   │   └── Medici.js                # Gestione medici
│   │
│   ├── config/
│   │   ├── ImpostazioniServiziTerzi.js
│   │   ├── ImpostazioniFlussoM.js
│   │   ├── ImpostazioniFlussoSIAD.js
│   │   ├── ImpostazioniFlussoHOSPICE.js
│   │   ├── ImpostazioniFlussoARSFAR.js
│   │   ├── ImpostazioniFlussoRSA.js
│   │   ├── ImpostazioniMail.js
│   │   ├── StruttureDistrettiPerProvincia.js
│   │   └── sicilia/
│   │       └── messina.js           # Config preconfigurata Messina
│   │
│   ├── classi/
│   │   └── Assistito.js             # Classe dati assistito
│   │
│   ├── db/
│   │   ├── DBHelper.js
│   │   └── asp_esenzioni.sql
│   │
│   ├── grid/                        # Template report HTML
│   │
│   ├── Utils.js                     # Utility comuni
│   ├── Indicatori.js                # Indicatori LEA
│   ├── Procedure.js
│   ├── Stipendi.js
│   ├── CryptHelper.js
│   └── api/
│       └── APIHelper.js
│
├── config/
│   └── config_example.json          # Template configurazione
│
└── example.js                       # Esempio di utilizzo

Dipendenze Principali

| Categoria | Librerie | |---|---| | HTTP / Scraping | axios, cheerio, puppeteer, puppeteer-extra | | Database | sqlite3, mysql, knex, mdb-reader, lokijs, ioredis | | Documenti | exceljs, xlsx, docx, pdf-lib, libreoffice-convert | | Email | nodemailer, eml-format, @freiraum/msgreader | | Sicurezza | openpgp, argon2, passport, passport-spid | | File | fs-extra, adm-zip, archiver, unzipper, chokidar | | Utilita | lodash, moment-timezone, xml2js, stream-json, winston | | AI | @google/generative-ai |


Configurazione

Creare un file config/config.json partendo dal template:

{
    "ts_username": "",
    "ts_password": "",
    "nar_username": "",
    "nar_password": "",
    "nar2_username": "",
    "nar2_password": ""
}

Licenza

MIT - Roberto De Domenico