Un calcolatore che parte da una retribuzione annua lorda e restituisce il netto annuo e mensile, con tutte le voci trattenute lungo la strada: contributi previdenziali, IRPEF, detrazioni, addizionali regionale e comunale.
Accanto a ogni voce c'è la formula applicata, i valori sostituiti, l'articolo di legge da cui viene il parametro e lo stato di verifica di quella fonte. Le regole fiscali non stanno nel codice: stanno in un file di regole per anno d'imposta, e il motore le esegue.
Il profilo calcolato è uno solo, dichiarato in pagina: lavoratore dipendente privato, tempo indeterminato, full time, CCNL Terziario Distribuzione e Servizi, residente a Milano, iscritto INPS dopo il 1995, nessun familiare a carico.
Il prototipo: index.html. Un file solo, nessuna dipendenza, nessun build. Si apre con un doppio click.
Dalla stessa funzione si derivano tre viste, nella stessa pagina.
| Vista | Domanda a cui risponde |
|---|---|
| Dipendente | con questa RAL quanto prendo netto, e cosa mi trattengono |
| Azienda | quanto costa questa persona, e dov'è il cuneo |
| Trattativa | quale RAL serve per un netto obiettivo |
La vista Azienda non calcola un proprio netto: lo prende dalla stessa funzione che alimenta la vista Dipendente. La vista Trattativa inverte quella funzione e poi la richiama sulla RAL che ha trovato. Sullo stesso input le tre viste danno lo stesso numero perché chiamano lo stesso codice.
Cambiando l'anno d'imposta in interfaccia si aggiornano tutte e tre. Il rulebook copre 2024, 2025 e 2026.
RAL 30.000 euro, anno 2026, Milano, nessun familiare a carico, 14 mensilità.
| Grandezza | Valore |
|---|---|
| Contributi previdenziali del lavoratore | 2.757,00 € |
| Reddito imponibile | 27.243,00 € |
| IRPEF lorda | 6.265,89 € |
| Detrazioni e crediti d'imposta | 3.044,29 € |
| IRPEF netta | 3.221,60 € |
| Addizionali regionale e comunale | 595,88 € |
| Netto annuo | 23.425,52 € |
| Netto mensile medio | 1.673,25 € |
| Costo azienda, TFR escluso | 39.144,00 € |
| Cuneo | 15.718,48 €, il 40,16% del costo |
Trentanove casi golden coprono i punti di discontinuità delle detrazioni, le soglie delle misure sul cuneo, il massimale contributivo e i confini fra un anno e l'altro. I valori attesi sono stati derivati dalle fonti prima che il motore esistesse, così che il confronto non avvenga fra il codice e sé stesso. PROCESSO.md racconta chi li ha scritti e con quali controlli.
node test/tutti.jsUndici banchi di prova, uscita 0 se passano tutti. Oltre ai golden, i banchi percorrono il dominio da zero a 300.000 euro e chiedono che ogni discesa del netto sia attribuita a una soglia dichiarata nel rulebook: il netto non è monotono, e nel 2026 scende in quattro punti. Poi l'inversa reinvertita che torna al punto di partenza, la coerenza fra le tre viste sullo stesso input, e il codice incorporato nella pagina identico parola per parola a quello del repository.
Un banco controlla una cosa diversa dagli altri. run-provenienza.js nasce da tre modifiche introdotte di proposito che avevano attraversato tutti gli altri banchi senza essere viste, e nessuna toccava un numero: uno stato di verifica promosso, una norma sostituita accanto al valore giusto, due etichette della catena scambiate fra loro. Un numero corretto con una spiegazione sbagliata resta un errore, e i banchi ora lo cercano.
I 39 casi girano anche dentro la pagina, al caricamento, sul motore che la pagina usa davvero. L'esito si legge in fondo.
Prima di scrivere il motore ho raccolto il netto calcolato da tre calcolatori affermati per cinque RAL, con URL e data. Servivano come sistema d'allarme: se il motore si fosse allontanato da tutto il mercato, o avevo ragione e lo dimostravo con le norme, o avevo un errore e lo trovavo prima della consegna.
| RAL | CUNEO | PMI.it | Fiscomania.com |
|---|---|---|---|
| 20.000 | 17.432,62 | 17.920 | 17.250 |
| 30.000 | 23.425,52 | 23.532 | 23.343 |
| 35.000 | 26.032,21 | 26.097 | 24.872 |
| 50.000 | 32.567,77 | 32.568 | 32.472 |
| 80.000 | 47.338,56 | 47.468 | 47.371 |
Tre scarti superano l'uno per cento, e per tutti e tre c'è una spiegazione normativa scritta. Il più grosso, 1.160 euro a RAL 35.000, viene da un calcolatore che applica ancora l'esonero contributivo del 2024, abrogato dal 2025. Il dettaglio, con le citazioni, sta in test/confronto-mercato.md.
I calcolatori raccolti erano tre e in tabella ne restano due. Il terzo è Talent.com, che diverge fra il 9,5 e il 15,7 per cento su tutte e cinque le RAL. L'ho tenuto fuori dal confronto perché test/confronto-mercato.md lo qualificava come fonte debole per il caso italiano 2026 già in fase di raccolta, prima di conoscere i numeri del motore, e la causa dello scarto è scritta lì.
Il rulebook ha 408 parametri con fonte. Ognuno dichiara il proprio stato di verifica, e quello stato viaggia dentro il risultato del calcolo fino allo schermo.
| Stato | Parametri | Significato |
|---|---|---|
| fonte primaria letta | 100 | il testo dell'atto è stato letto su fonte istituzionale, con citazione puntuale |
| fonte primaria citata da secondarie concordanti | 228 | due fonti professionali indipendenti riportano lo stesso valore con gli estremi dell'atto |
| non confermato | 79 | tutto il resto, dichiarato invece che stimato |
| inferenza di continuità | 1 | valore riportato uguale all'anno precedente senza conferma |
Sul caso base del 2026 il motore tocca tredici fonti distinte, otto delle quali a fonte primaria letta. In pagina, aprendo una riga di dettaglio, si vede la formula, i valori sostituiti, l'articolo di legge e un badge con lo stato della fonte. FONTI.md elenca le norme una per una.
Fra il 2024 e il 2026 non cambiano soltanto dei numeri. Cambiano quali istituti esistono e in che punto della catena agiscono.
Nel 2024 il sostegno ai redditi bassi passava da un esonero contributivo, che agisce prima dell'imponibile fiscale. Dal 2025 lo stesso obiettivo passa da una somma non imponibile più un'ulteriore detrazione, che agiscono in due punti diversi e a valle. Nel 2026 la seconda aliquota IRPEF scende dal 35 al 33 per cento, e compare una riduzione delle detrazioni sopra i 200.000 euro di reddito complessivo.
Un motore con la matematica scritta dentro il codice, davanti a un cambiamento di questo tipo, va riscritto. Qui il codice esegue istituti dichiarati in un file, ognuno con il proprio punto di innesto sulla catena e il proprio stato di attivazione per anno, e la differenza fra due anni è solo di contenuto.
rulebook/2024.json 6 istituti dichiarati, 3 attivi
rulebook/2025.json 6 istituti dichiarati, 4 attivi
rulebook/2026.json 6 istituti dichiarati, 5 attivi
Un istituto spento resta nel rulebook e resta visibile in pagina, dichiarato come modellato e inerte.
La catena ha sei punti fissi, anch'essi nel rulebook: contributi del lavoratore, reddito imponibile, IRPEF lorda, detrazioni, addizionali locali, importi aggiunti al netto. Il motore legge dove ogni istituto si aggancia e lo esegue lì. Non c'è nessun if sull'anno né sul nome di un istituto.
C'è una seconda ragione, ed è quella da cui è partito il progetto. Guardando come sono fatti gli strumenti che già esistono online, compresi i nove pubblicati da Jet HR, si vede che sono calcolatori separati che ricostruiscono ciascuno un pezzo della stessa catena: l'IRPEF sta dentro il netto, il netto sta dentro il costo azienda, il fringe benefit dipende dagli scaglioni. Ogni legge di bilancio va riportata dentro tutti, uno per uno. Con un corpo di regole solo e più viste che lo interrogano, la legge di bilancio si applica in un posto solo. Le tre viste di questo prototipo servono a mostrare che la cosa funziona.
Inserita la RAL e premuto Calcola, la pagina mostra il netto annuo e quello mensile. Il resto emerge dopo, e chi ha trenta secondi non lo incontra.
La macchina del tempo. Si cambia anno d'imposta e la pagina dice quanto cambia il netto e quale unità di rulebook è responsabile. L'attribuzione avviene per sostituzione progressiva: si sostituisce una unità alla volta e si rimisura, quindi la somma delle attribuzioni torna al totale. A RAL 30.000 il passaggio dal 2024 al 2026 vale 900,03 euro, e viene dall'ulteriore detrazione accesa e dall'esonero contributivo spento.
L'inversa. Dal netto obiettivo alla RAL, con la gestione dei netti irraggiungibili: certi valori cadono dentro un salto lasciato da un istituto a soglia secca, e nessuna RAL li produce. La pagina lo dice, e mostra i due valori raggiungibili più vicini.
La curva delle aliquote. L'aliquota effettiva dice quanta parte della RAL non arriva in tasca. La marginale dice quanta parte del prossimo aumento non ci arriverà. È misurata aggiungendo cento euro alla RAL e richiamando il motore, perché il netto è una funzione a gradini e una derivata puntuale su una funzione a gradini non descriverebbe niente. La marginale si scompone in cinque addendi che tornano al totale, ognuno con la norma accanto. Nel 2026 la marginale più alta è il 60,71 per cento a RAL 38.500, dove la tabella IRPEF dichiara il 33: la differenza è il ritiro di due detrazioni insieme.
Il registro delle assunzioni. Trentasette voci che raccolgono ogni semplificazione dichiarata: le assunzioni del caso, le convenzioni di calcolo, i parametri letti e non applicati, il perimetro di ogni istituto. Nessuna è scritta nella pagina: arrivano dal rulebook o dall'audit trail del motore, con le stesse parole.
Le leve a fiscalità agevolata. Otto leve dichiarate nel rulebook con le loro soglie e le loro fonti, mostrate senza calcolarne l'effetto. Per ognuna la pagina dice cosa servirebbe sapere per metterci un numero. Il motivo per cui il conto non si fa sta in ASSUNZIONI.md.
Il profilo modellato è uno: lavoratore dipendente privato, tempo indeterminato, full time, CCNL Terziario Distribuzione e Servizi, residente a Milano, iscritto INPS dopo il 1995, nessun familiare a carico.
Fuori scope: apprendistato, part-time, dirigenti, tempo determinato, altri CCNL, regimi per impatriati e ricercatori, conguaglio di fine anno, meccanica di acconto e saldo delle addizionali, TFR erogato in busta, straordinari, trasferte, familiari a carico, calcolo puntuale della tredicesima e della quattordicesima.
ASSUNZIONI.md elenca ogni semplificazione con il motivo e l'impatto sul risultato.
Due parametri non hanno un valore unico e vero, e sono esposti in interfaccia come campi modificabili con il loro default e la loro fonte: l'aliquota contributiva datoriale aggregata e il tasso INAIL. Il commercio non ha un'aliquota datoriale unica, e una vista che promette "quanto costa questa persona" e risponde "non calcolabile" non serve. Esporli come campi permette a chi conosce il valore della propria azienda di correggerlo.
rulebook/ i tre anni, più lo schema documentato campo per campo
src/ dieci moduli, tutti funzioni pure che girano in Node
test/ undici banchi di prova, i 39 casi golden, il confronto di mercato
index.html il prototipo, 774 KB, tutto dentro
src/ contiene circa 3.500 righe, e il modulo più grande è il motore. Nessuna dipendenza runtime: niente framework, niente CDN, niente build. I grafici sono SVG, senza librerie.
La pagina pesa 774 KB perché contiene i tre rulebook interi con le loro fonti, i 39 casi golden con le derivazioni e i dieci moduli. È il prezzo di un file che funziona aperto da file:// senza rete.
ASSUNZIONI.mdogni semplificazione, con motivo e impattoFONTI.mdle norme con il loro stato di verificaROADMAP.mdcosa serve per portarlo in produzionePROCESSO.mdcome è stato costruito, incluso l'uso dell'AI e i controlli adottatirulebook/schema.mdlo schema del rulebook, campo per campo
Questo repository è la mia risposta alla task di selezione per il ruolo Product Builder nel team Cost-Saving di Jet HR. Il codice è mio, l'ho scritto con assistenza di modelli linguistici, e PROCESSO.md racconta come e con quali controlli.