Moduli Abilitati
Gerarchia Pacchetti licenza + Profilo attività + Permessi utente — Pannello SUPERADMIN
Scopo del pannello
- Gestire le licenze commerciali dei workspace: quale cliente ha acquistato quali pacchetti (FATTURAZIONE, MAGAZZINO, CONTABILITA, ecc.).
- Separare concetto di licenza da profilo fiscale: un workspace che ha il pacchetto MAGAZZINO ma profilo "Studio Medico" non vedrà comunque il magazzino (il profilo lo rende non rilevante).
- Centralizzare la configurazione in un unico pannello accessibile solo a SUPERADMIN, senza dover modificare file di configurazione o database manualmente.
- Tracciare le attivazioni/disattivazioni con timestamp e operatore per audit.
Per decidere se un modulo (es. Magazzino, Sistema TS, Corrispettivi) è visibile a un utente di un workspace, NOX applica tre filtri indipendenti in intersezione. Tutti e tre devono dire «sì» per mostrare il modulo.
Pacchetto licenza
Risponde a: «Il cliente ha pagato questo set di funzionalità?» — dominio commerciale.
Profilo attività
Risponde a: «Questa tipologia di impresa può legalmente/utilmente usare questo modulo?» — dominio fiscale e di pertinenza.
Permesso utente
Risponde a: «Questo singolo utente del workspace è autorizzato a vedere il modulo?» — dominio operativo/ruolo.
Prima della certificazione v 2.2 esistevano solo due configurazioni scollegate:
- Profilo attività: stringa in Parametri, usata per terminologia ma non filtrava i menu
- menuConfig utente: priorità assoluta, permetteva conflitti silenziosi (un dentista poteva attivarsi «magazzino» senza che nessuno lo notasse)
Mancava una separazione netta tra:
| Concetto | Prima | Ora (v 2.2) |
|---|---|---|
| Licenza commerciale (cosa ho pagato) | Non esisteva | Livello 1 (Pacchetti) |
| Pertinenza fiscale (cosa ha senso per me) | Solo terminologia | Livello 2 (Profilo) |
| Permesso operativo (cosa vede il singolo utente) | Unico filtro attivo | Livello 3 (menuConfig) |
I 7 pacchetti commerciali disponibili:
| Pacchetto | Moduli inclusi | Note |
|---|---|---|
| BASE | Dashboard, Soggetti, Catalogo, Aliquote IVA, Parametri, Utenti, GDPR, Backup, SDI | Sempre attivo, non disattivabile |
| FATTURAZIONE | Documenti, Listini, Sconti, Scadenzario, Lettere di Intento | Core per qualsiasi attività commerciale |
| MAGAZZINO | Movimenti, Giacenze, Ubicazioni, Inventari, Lotti | Per produttori, commercianti, farmacie |
| CONTABILITA | Piano dei Conti, Prima Nota, Registri IVA, Liquidazione, F24, Dichiarazione annuale, Conservazione | Contabilità ordinaria e semplificata |
| CORRISPETTIVI | Corrispettivi giornalieri (art. 24 DPR 633/72) | Vendita al dettaglio |
| VENDITE_B2B | CRM, Agenti, Provvigioni, Spedizioni | Aziende con rete vendita |
| SISTEMA_TS | Sistema Tessera Sanitaria, Opposizioni paziente | SOLO professionisti sanitari (DM 31/07/2015) |
Caratteristiche
- Attivazione tracciata:
attivato_il,attivato_da - Disattivazione tracciata:
disattivato_il,disattivato_da(non elimina il record, marca attivo=false) - BASE sempre ON: il toggle è disabilitato, il pacchetto è tecnicamente impossibile da disattivare
- Effetto immediato: dopo il salvataggio, alla prima chiamata API l'utente non vedrà più i moduli del pacchetto disattivato
Il profilo attività (Parametri → Dati Aziendali) definisce quali moduli sono rilevanti per quel tipo di impresa, nell'intersezione con i pacchetti attivi.
12 profili preconfigurati:
| Profilo | Moduli tipicamente rilevanti |
|---|---|
| STUDIO_MEDICO | Documenti, Scadenzario, Sistema TS, Prima Nota, Registri IVA, Conservazione |
| STUDIO_NATUROPATICO | Documenti, Scadenzario, Prima Nota, Registri IVA (no Sistema TS perché non medicina riconosciuta) |
| STUDIO_DENTISTICO | Documenti, Scadenzario, Sistema TS, Magazzino (materiali), Listini |
| FARMACIA | Fatturazione + Corrispettivi + Magazzino + Sistema TS + Contabilità completa + Lettere di Intento |
| STUDIO_LEGALE / COMMERCIALISTA | Fatturazione + Scadenzario + Prima Nota + Registri IVA (no magazzino, no corrispettivi) |
| FERRAMENTA / ELETTRONICA_HIFI | Fatturazione + Corrispettivi + Magazzino + Contabilità + CRM + Spedizioni |
| VERNICIATURA | Fatturazione + Magazzino + Contabilità (solo B2B, no corrispettivi) |
| ASSOCIAZIONE | Documenti (ricevute) + Scadenzario (quote) + CRM (soci) |
| AGENTE_COMMERCIO | Fatturazione + CRM + Provvigioni (no magazzino, no corrispettivi) |
| GENERICO | Tutti rilevanti (fallback) |
profili_moduli_preset contiene per ciascun profilo una riga per modulo con flag rilevante + campo motivazione con riferimento normativo o spiegazione operativa.UI nei Parametri
Nella pagina Dati Aziendali, accanto alla label "Profilo Attività" c'è un pulsante «Moduli» che apre una modal con le due colonne:
- Auto-attivati (verde): moduli rilevanti per il profilo corrente
- Nascosti per questo profilo (grigio): moduli disponibili ma non pertinenti (tooltip con motivazione)
Ogni utente ha un suo menuConfig che contiene le chiavi modulo con valore true/false.
Comportamento in Modifica Utente → Moduli
- I moduli non permessi dai livelli 1+2 appaiono disabilitati, barrati, con badge BLOCCATO e tooltip che spiega il motivo (es. «Pacchetto MAGAZZINO non attivo» oppure «Non rilevante per il profilo STUDIO_MEDICO»)
- I moduli permessi da 1+2 sono toggolabili liberamente dall'admin del cliente
- Anche se l'admin del cliente forza un toggle, il backend rifiuterà la chiamata API del modulo bloccato (HTTP 403)
La formula che applica il sistema:
pacchetto_attivo(workspace, pacchetto_di(modulo)) // livello 1
AND profilo_compatibile(workspace.profilo, modulo) // livello 2
AND utente_abilitato(utente.menuConfig, modulo) // livello 3
Se uno solo dei tre filtri ritorna false, il modulo non è visibile.
- TU come SUPERADMIN: apri
/admin/pacchetti, seleziona il workspace del nuovo cliente, spunta i pacchetti acquistati. Salva. (BASE già attivo.) - Admin del cliente: apre Parametri → Dati Aziendali, seleziona il suo Profilo Attività. Clicca il pulsante "Moduli" per vedere l'anteprima dei moduli attivati/nascosti. Salva parametri.
- Admin del cliente: va in Utenti → Modifica Utente, configura i permessi specifici per ciascun dipendente (es. la commessa vede solo Corrispettivi, il contabile vede solo Registri IVA + Piano Conti).
- Gli utenti operano: ogni volta che aprono un menu o chiamano un'API, i tre filtri vengono applicati automaticamente.
| Scenario | Pacchetti | Profilo | menuConfig utente | Risultato |
|---|---|---|---|---|
| Cassiere farmacia | BASE + FATT + MAG + CORR + STS + CONT | FARMACIA | corrispettivi=on | ✅ Vede Corrispettivi |
| Contabile farmacia | Come sopra | FARMACIA | registro-iva=on, corrispettivi=off | ✅ Vede Registro IVA ❌ Non vede Corrispettivi (livello 3) |
| Medico senza pacchetto CORR | BASE + FATT + STS + CONT (NO CORR) | STUDIO_MEDICO | qualunque | ❌ Corrispettivi non visibili (livello 1: pacchetto mancante) |
| Studio dentistico base | BASE + FATT + STS + MAG | STUDIO_DENTISTICO | magazzino=on, sistema-ts=on | ✅ Vede entrambi (compatibili con profilo) |
| Commercialista con tutti i pacchetti | Tutti i 7 | STUDIO_COMMERCIALISTA | sistema-ts=on | ❌ Sistema TS non visibile (livello 2: non rilevante per profilo) |
| Ferramenta venditore esterno | BASE + FATT + MAG + CORR + VENDITE_B2B | FERRAMENTA | spedizioni=on, magazzino=off | ✅ Vede Spedizioni ❌ Non vede Magazzino (livello 3) |
Sidebar / Topbar
Ogni voce di menu viene filtrata da AuthService.isMenuEnabled(key) che applica in ordine livello 1 → 2 → 3. Il menu della voce bloccata non compare proprio: l'utente non vede neanche che esiste.
Chiamate API
Il middleware backend richiedeModulo(moduloKey) sui route sensibili:
- Passa il controllo se tutti e 3 i livelli approvano
- Ritorna HTTP 403 Forbidden con JSON:
{"error": "Modulo 'X' non accessibile: <motivo>", "dettaglio": {...}} - SUPERADMIN bypassa i livelli 2 e 3 (ma non 1)
Endpoint /api/me/moduli-attivi
Restituisce l'elenco dei moduli effettivamente visibili all'utente corrente, con dettaglio di ciascun check (pacchettoOk, profiloOk, utenteOk) per debug.
/admin/pacchettiDalla topbar, il pulsante dorato «Moduli Abilitati» (con icona inventory) è visibile solo per SUPERADMIN.
Layout della pagina
- Selettore workspace: dropdown con i workspace disponibili
- Griglia di card pacchetti: una card per ciascun pacchetto (7 totali), con toggle di attivazione e lista dei moduli inclusi
- Footer sticky: appare solo se ci sono modifiche non salvate, con pulsanti Salva e Annulla
Aspetto delle card
- Card attiva: bordo verde, opacità piena
- Card inattiva: bordo grigio, opacità 55%
- Card BASE: toggle disabilitato con etichetta "sempre attivo"
- Modifica i toggle dei pacchetti
- Il footer sticky mostra il numero di modifiche pendenti
- Clicca Salva modifiche: PUT
/api/pacchetti/workspace/:wsId - Il backend aggiorna
pacchetti_workspaceriga per riga: se il pacchetto cambia da attivo a inattivo (o viceversa), registradisattivato_il/daoattivato_il/da - Messaggio di conferma "Pacchetti aggiornati". La lista viene ricaricata.
Scenario: il cliente cambia contratto e rimuove il pacchetto MAGAZZINO.
- Avvisa il cliente: i suoi utenti perderanno l'accesso ai moduli magazzino al prossimo refresh della pagina
- Verifica transizioni aperte: assicurati che non ci siano movimenti di magazzino in bozza o inventari in corso che l'utente dovrà comunque completare
- Disattiva il toggle MAGAZZINO in
/admin/pacchettidel workspace - Salva
- I dati storici non vengono cancellati: restano consultabili solo da SUPERADMIN, che bypassa il filtro 2 ma non il 1 (quindi vede solo moduli del pacchetto BASE+altri attivi)
Tabelle nel DB master gestione
| Tabella | Scopo |
|---|---|
pacchetti_workspace | Pacchetti attivi per workspace (con attivato/disattivato_il/da) |
moduli_catalogo | Catalogo dei 25 moduli con mapping al pacchetto di appartenenza |
profili_moduli_preset | Per ciascun profilo attività, quali moduli sono rilevanti (con motivazione) |
Endpoint API
| Metodo | Path | Scopo |
|---|---|---|
| GET | /api/pacchetti/moduli-catalogo | Lista completa dei 25 moduli |
| GET | /api/pacchetti/pacchetti-disponibili | 7 pacchetti con moduli raggruppati |
| GET | /api/pacchetti/profili/:profilo/preset | Preset moduli rilevanti per profilo |
| GET | /api/pacchetti/workspace/:wsId | Pacchetti attivi workspace [SUPERADMIN] |
| PUT | /api/pacchetti/workspace/:wsId | Aggiorna pacchetti [SUPERADMIN] |
| GET | /api/pacchetti/workspace/:wsId/moduli-leciti | Lista moduli permessi da livelli 1+2 |
| GET | /api/me/moduli-attivi | Moduli visibili all'utente corrente (1+2+3) |
Il ruolo SUPERADMIN ha comportamento speciale nella gerarchia:
| Livello | SUPERADMIN |
|---|---|
| 1. Pacchetto | ❌ NON bypassabile — se il pacchetto non è attivo, il modulo non esiste proprio (anche per lo stesso SUPERADMIN) |
| 2. Profilo | ✅ Bypassato — il SUPERADMIN vede anche moduli non rilevanti per il profilo, per poter fare diagnosi o setup avanzato |
| 3. menuConfig | ✅ Bypassato — il SUPERADMIN ignora anche i permessi utente specifici, per poter operare su tutti i dati del workspace |
Nel catalogo moduli, alcune voci sono marcate come indispensabile: true e non sarebbero mai disattivabili. In pratica questa rigidità crea problemi: un naturopata forfettario non ha bisogno dei Registri IVA, un professionista senza cassa non vuole vedere la voce Rivalsa INPS, un consulente non spedisce nulla quindi non serve la voce Spedizioni. Dalla versione 2.2, il backend declassa automaticamente certi moduli in base al contesto letto dai Parametri aziendali (tab Fatturazione-Cassa).
I 3 tipi di moduli
| Categoria | Comportamento | Moduli inclusi |
|---|---|---|
| 🔒 Core di sistema | Sempre obbligatori per tutti i regimi/attività. Il toggle resta bloccato. | dashboard, soggetti, catalogo, aliquote-iva, parametri, utenti, gdpr, backup, sdi, documenti |
| ⚖️ Fiscali condizionali | Obbligatori solo se il regime/cassa/anagrafica/attività lo richiedono. Altrimenti declassati a disattivabili. | registro-iva, corrispettivi, sistema-ts, esterometro, intrastat-ue, split-payment, reverse-charge, lettere-intento, autofatture, ritenuta-acconto, rivalsa-inps, cassa-previdenziale, esigibilita-differ |
| ✅ Operativi sbloccabili | Nel DB sono marcati indispensabili ma in pratica sono funzionali al business: l'admin decide se mostrarli, indipendentemente dal regime. | listini, scadenzario, magazzino, piano-dei-conti, prima-nota, spedizioni |
Le 4 regole di declassamento fiscale
L'endpoint GET /api/pacchetti/workspace/:wsId/moduli-config legge 4 campi dai Parametri del workspace e applica le regole sotto:
| Condizione Parametri | Moduli declassati | Motivo |
|---|---|---|
| Regime fiscale ∈ {RF19 forfettario, RF02 minimi} | registro-iva, corrispettivi, aliquote-iva, esterometro, intrastat-ue, split-payment, reverse-charge, lettere-intento, autofatture, ritenuta-acconto, esigibilita-differ | FORFETTARIO |
Cassa previdenziale vuota (tipoCassaPrevId IS NULL) | rivalsa-inps, cassa-previdenziale | NO_CASSA_PREV |
| Tipo anagrafica ∈ {PERSONA_GIURIDICA, ENTE_PUBBLICO} | ritenuta-acconto, rivalsa-inps | NON_PROFESSIONISTA |
| Tipo attività non sanitaria (diverso da STUDIO_MEDICO, STUDIO_DENTISTICO, FARMACIA) | sistema-ts | NON_SANITARIO |
| (sempre) | listini, scadenzario, magazzino, piano-dei-conti, prima-nota, spedizioni | OPERATIVO |
rivalsa-inps in un workspace SRL senza cassa avrà motiviDeclass: ['NO_CASSA_PREV', 'NON_PROFESSIONISTA'], utile per mostrare tooltip esplicativi in UI.Esempi pratici (stessa azienda, 3 regimi diversi)
| Scenario | Regime | Cassa | Anagrafica | Attività | registro-iva | sistema-ts | ritenuta-acconto | rivalsa-inps | listini |
|---|---|---|---|---|---|---|---|---|---|
| A — Naturopata forfettario | RF19 | — | PF | NATUROPATICO | ✅ sbloccato | ✅ sbloccato | ✅ sbloccato | ✅ sbloccato | ✅ sbloccato |
| B — Medico ordinario | RF01 | ENPAM | PF | MEDICO | 🔒 obbligatorio | 🔒 obbligatorio | libero | libero | ✅ sbloccato |
| C — SRL generica | RF01 | — | PG | GENERICO | 🔒 obbligatorio | ✅ sbloccato | ✅ sbloccato | ✅ sbloccato (2 motivi) | ✅ sbloccato |
Legenda: 🔒 obbligatorio = toggle bloccato, l'utente non può disattivarlo. ✅ sbloccato = toggle libero, l'admin decide. libero = lo era già (nel DB indispensabile: false).
Response API con nuovi campi
GET /api/pacchetti/workspace/:wsId/moduli-config
{
"profilo": "STUDIO_NATUROPATICO",
"regime": "RF19",
"forfettario": true,
"contesto": {
"regime": "RF19",
"cassaPrevId": null,
"tipoAnagrafica": "PERSONA_FISICA",
"tipoAttivita": "STUDIO_NATUROPATICO"
},
"pacchetti": ["BASE", "FATTURAZIONE", "CONTABILITA", "MAGAZZINO"],
"moduli": [
{
"moduloKey": "registro-iva",
"indispensabile": false,
"disabilitato": false,
"declassato": true,
"motiviDeclass": ["FORFETTARIO"],
"motivoDisab": null,
...
},
{
"moduloKey": "listini",
"indispensabile": false,
"disabilitato": false,
"motiviDeclass": ["OPERATIVO"],
...
}
]
}
Codice — dove modificare le liste
Per aggiungere/togliere moduli dalle 4 categorie, editare backend/services/modulo-access.service.js:
MODULI_IVA_DECLASSATI— moduli liberati dal regime forfettarioMODULI_CASSA_PREV— moduli liberati se nessuna cassaMODULI_SOLO_PROFESSIONISTA— moduli liberati per societàMODULI_SANITARI— moduli liberati per attività non sanitarieMODULI_OPERATIVI_SBLOCCABILI— moduli sempre liberi a prescindere dal contesto
Tutti e 7 attivi di default (BASE obbligatorio, gli altri 6 accesi). Il SUPERADMIN poi restringe in base al contratto.
No. I dati restano nel database. Vengono solo nascosti dai menu e il backend rifiuta nuove operazioni. Riattivando il pacchetto i dati tornano accessibili.
No, mai. Solo SUPERADMIN. La pagina
/admin/pacchetti ritorna 403 agli admin cliente.La configurazione viene salvata subito. Gli utenti vedranno i nuovi moduli rilevanti al prossimo refresh/login. I dati dei moduli che non sono più rilevanti non vengono cancellati, solo nascosti.
Apri la console browser (F12) e chiama
GET /api/me/moduli-attivi. Il campo dettaglio per ciascun modulo mostra i flag pacchettoOk / profiloOk / utenteOk.Sì, inserendo una riga in
moduli_catalogo con modulo_key, pacchetto_key (uno dei 7 esistenti o nuovo), nome, descrizione, ordine. Poi aggiornare i profili_moduli_preset per indicare per quali profili è rilevante. Richiede accesso DB.