Skip to main content

Modello Multi-Tenant: Isolamento Dati

Panoramica

La piattaforma implementa un modello multi-tenant con isolamento a livello di database. Ogni tenant (ristorante, punto vendita) dispone di un database MongoDB dedicato. Questo approccio garantisce separazione completa dei dati, semplifica backup e restore per singolo tenant e permette scaling indipendente.

Convenzioni di Naming dei Database

La piattaforma gestisce tre livelli di dati, ciascuno con la propria convenzione:

PrefissoPatternEsempioUso
t_t_{tenantId}t_ristorante01Dati operativi del singolo ristorante
r_r_{resellerCode}r_ACMEDati cross-tenant del reseller (manutenzioni, installazioni)
nessunopos_platformpos_platformDati condivisi della piattaforma (tenant registry, licenze, audit)

Come Funziona l'Isolamento

Il flusso di isolamento segue questi passi:

  1. Il client invia una richiesta con header Authorization: Bearer <JWT>
  2. L'API Gateway valida il JWT e estrae tenantId dal token (claim Keycloak o payload HS256)
  3. Il gateway popola ctx.meta.tenantId nel contesto Moleculer
  4. Il servizio destinatario usa il mixin appropriato per selezionare il database corretto
  5. Tutte le query operano esclusivamente sul database del tenant

Non esiste alcun modo per un servizio di accedere accidentalmente ai dati di un altro tenant: la selezione del database avviene a livello di mixin, non di query.

Pool di Connessioni Condiviso

Tutti i servizi condividono un singleton connection pool verso il cluster MongoDB. Il pool viene creato una sola volta alla prima connessione e riutilizzato da tutte le istanze dei mixin.

Parametri di configurazione principali (variabili ambiente):

MONGO_BASE_URI=mongodb+srv://user:pass@cluster.mongodb.net
MONGO_MAX_POOL_SIZE=500 # Connessioni massime (default: 500)
MONGO_MIN_POOL_SIZE=50 # Connessioni minime (default: 50)
MONGO_SOCKET_TIMEOUT=45000 # Timeout socket in ms

Il pool e scalato per supportare migliaia di tenant senza creare connessioni dedicate per ciascuno.

Caching Multi-Tenant

Il Redis cacher di Moleculer deve distinguere i dati cached di tenant diversi. I mixin implementano getCacheKey() che antepone il tenantId (o resellerCode) alla chiave di cache standard:

tenantId:nomeServizio.azione:parametriHash

Questo impedisce che una richiesta di un tenant riceva dati cached di un altro tenant. Le azioni di scrittura (create, update, remove) invalidano automaticamente la cache del servizio.

Dati della Piattaforma

Il database pos_platform contiene dati condivisi tra tutti i tenant:

  • Tenant registry: elenco tenant, configurazioni, licenze
  • Reseller registry: anagrafica reseller
  • Audit log: log immutabile delle sessioni di supporto
  • Device registry: dispositivi registrati e associazioni licenza

I servizi che accedono a pos_platform usano PlatformDbMixin che non richiede tenantId nel contesto.

Aggiungere un Nuovo Tenant

Per creare un nuovo tenant sulla piattaforma:

  1. Creare il record in pos_platform.tenants tramite tenant-management.create
  2. Il database t_{tenantId} viene creato automaticamente da MongoDB al primo inserimento
  3. Configurare i gruppi Keycloak per gli utenti del nuovo tenant
  4. Generare un OTP per registrare il primo dispositivo

Non e necessario creare manualmente il database o le collezioni: MongoDB li crea on-demand.

FAQ

D: Cosa succede se una richiesta arriva senza tenantId? R: Il TenantDbMixin fa fallback sul database pos_platform. In produzione, i servizi che richiedono un tenant dovrebbero verificare esplicitamente la presenza di tenantId e rifiutare la richiesta se assente.

D: Posso fare query cross-tenant (es. report aggregati)? R: Non direttamente tramite i mixin standard. I servizi di reporting platform-level devono iterare sui tenant registrati e aggregare i risultati. Il ResellerDbMixin supporta dati cross-tenant a livello reseller.

D: Come migro i dati da un tenant a un altro? R: Usare il servizio tenant-clone che copia collezioni tra database tenant, rimappando gli ID interni.

Vedi Anche

Questa pagina ti è stata utile?