Vai al contenuto sulla tecnologia
Torna alla home

Stack tecnologico

HansaChat è una chat aziendale europea con un livello operativo per i team sul campo, progettata, sviluppata e gestita da una sola persona. Questa pagina mostra con quali tecnologie è costruita ogni parte e perché sono state scelte.

Versioni e conteggi verificati a ottobre 2026.

Contati nei repository

servizi ConnectRPC con 179 RPC, tutti definiti in Protobuf
18
binari Go da un’unica codebase: API, worker, relay dell’outbox, amministrazione
4
piattaforme da un unico client: web, macOS, Windows, Linux, iOS, Android
6
lingue sul sito web pubblico
22
lingue dell’interfaccia nell’app
23
specifiche end-to-end Playwright su uno stack isolato
70

Come si incastrano i pezzi

Tre applicazioni condividono un unico edge e un unico cluster. Il sito web gestisce la fatturazione e il registro degli spazi di lavoro, il backend Go gestisce tutto ciò che avviene all’interno di uno spazio di lavoro e l’app web comunica con il backend tramite client ConnectRPC generati.

Client

Browser

Sito web e app web

Tauri

Contenitori desktop e mobile

hansa CLI

Script e agenti

Edge

Bunny.net CDN

TLS, caching, protezione DDoS

IONOS Managed Kubernetes, Germania

Traefik

Ingress per ogni applicazione

App web Vue + Vite

Build statica di Vue

API della chat

Go con ConnectRPC

  • Worker
  • Relay dell’outbox

Sito web Laravel + FrankenPHP

Fatturazione, registro, provisioning

NATS JetStream

Comandi ed eventi durevoli

Centrifugo

Distribuzione via WebSocket

Valkey Sentinel + HAProxy

Cache, presenza, sessioni

LiveKit

Media delle chiamate

Dati gestiti su IONOS

MariaDB

Un database per spazio di lavoro più un registro centrale

Object storage S3

File e avatar

Servizi esterni

ElevenLabs · LLM · Clef

Trascrizione, traduzione, triage

Creem · EmailLabs

Pagamenti ed e-mail

Fuori dal cluster

Cloudflare Workers D1

Controlli di stato esterni

Bunny Storage restic

Backup cifrati a Francoforte e Stoccolma

Il percorso di un messaggio

  1. Il client chiama il servizio dei messaggi tramite ConnectRPC.
  2. L’API accetta la richiesta solo dopo che NATS JetStream ha memorizzato il comando in modo durevole.
  3. Un worker scrive il messaggio e un evento di outbox nel database dello spazio di lavoro in un’unica transazione.
  4. Il relay dell’outbox pubblica l’evento confermato su NATS e Centrifugo.
  5. Ogni client aperto lo riceve via WebSocket; dopo un’interruzione, i client ricaricano lo stato di riferimento dall’API.

Backend della chat

Tutto ciò che avviene all’interno di uno spazio di lavoro gira in Go: messaggi, canali, file, chiamate, tempo reale, importazioni e il pacchetto operativo per le imprese di pulizia. Il sito web non tocca mai i dati degli spazi di lavoro.

Go 1.26

Quattro binari da un’unica codebase modulare: l’API, il worker dei messaggi, il relay dell’outbox e un comando di amministrazione protetto. Vengono distribuiti come binari statici in un’unica immagine leggera.

Perché

Una libreria standard solida, prestazioni prevedibili e una concorrenza semplice si adattano a un backend fatto di worker a lunga esecuzione. Un solo linguaggio per l’intero nucleo dello spazio di lavoro lo rende manutenibile da una sola persona.

ConnectRPC + Protobuf connect-go 1.20 · buf 1.71

18 servizi e 179 RPC sono definiti in Protobuf. buf genera il server Go e i client TypeScript con plugin locali, quindi nessuno schema lascia la macchina.

Perché

Un unico contratto serve i client web, desktop, mobile e da riga di comando. Non ci sono percorsi HTTP scritti a mano né parsing manuale delle risposte, e una modifica al contratto emerge come errore di compilazione anziché come guasto in fase di esecuzione.

Un database per spazio di lavoro MariaDB · sqlc

Ogni spazio di lavoro ha il proprio database MariaDB fisico. L’API individua lo spazio di lavoro dal suo dominio e apre il pool corrispondente; i worker lo individuano di nuovo autonomamente e non si fidano mai di un nome di database ricevuto in un messaggio di coda. Le query sono SQL semplice compilato in Go tipizzato con sqlc.

Perché

L’isolamento è strutturale, non un filtro aggiunto a ogni query. Esportazione, importazione, ripristino ed eliminazione funzionano per singola azienda.

NATS JetStream 2.10

Stream durevoli per comandi, job ed eventi, più uno stream dead-letter per i messaggi non elaborabili. Le scritture dei messaggi avvengono in 64 partizioni ordinate.

Perché

Un messaggio viene accettato solo dopo una conferma durevole. I messaggi di uno stesso canale restano in ordine, mentre i canali indipendenti vengono elaborati in parallelo.

Outbox transazionale

Le righe di dominio e l’evento in uscita vengono confermati nella stessa transazione. Un relay pubblica gli eventi confermati su NATS e Centrifugo, deduplicati tramite l’ID dell’evento, e registra gli errori per ritentarli.

Perché

Nessun evento perso o fantasma quando un processo si ferma tra la scrittura nel database e la pubblicazione.

Centrifugo v5

Consegna via WebSocket di messaggi, presenza, indicatori di digitazione e stato delle chiamate. I client si iscrivono con token di breve durata per canale, che l’API emette solo dopo aver verificato l’appartenenza allo spazio di lavoro.

Perché

Un server realtime dedicato tiene le connessioni di lunga durata fuori dal processo dell’API, e ogni token indica sia lo spazio di lavoro sia l’utente, così le identità provenienti da database separati non possono entrare in conflitto.

Object storage compatibile con S3 aws-sdk-go-v2

File e avatar sono conservati in IONOS Object Storage nell’UE e distribuiti tramite link firmati di breve durata.

Perché

L’archiviazione dei file scala indipendentemente dai database ed è cifrata a riposo lato server.

LiveKit 1.9

Un media server WebRTC self-hosted per le chiamate nei messaggi diretti e le chiamate di canale incentrate sull’audio, con videocamera e condivisione dello schermo.

Perché

Open source e installabile in proprio, così i media delle chiamate passano su un’infrastruttura gestita da HansaChat.

ElevenLabs Scribe

Trascrizione vocale per i messaggi vocali. La trascrizione è allegata al messaggio, ricercabile e traducibile come qualsiasi testo.

Perché

Le squadre sul campo parlano più di quanto scrivano.

Traduzione con LLM

Traduzione per singolo lettore tramite un’API compatibile con OpenAI. Ogni messaggio viene tradotto su richiesta, memorizzato in cache una sola volta per lingua di destinazione e saltato quando il lettore condivide già la lingua.

Perché

Una squadra multilingue lavora in un’unica conversazione mentre ogni membro legge nella propria lingua. Il fornitore resta sostituibile dietro un’unica interfaccia.

Cloudflare Clef

Un modello decisionale classifica i messaggi operativi per categoria, urgenza e grado di confidenza. Restituisce probabilità per domande prestabilite, non testo generato. Attualmente in fase pilota.

Perché

Non c’è output in testo libero da interpretare. I supervisori vedono cosa richiede attenzione; agire resta sempre una decisione umana.

go-pdf 0.9

I fogli ore e i rapporti di servizio in formato A4 vengono generati sul server.

Perché

Una libreria interamente in Go mantiene l’immagine del backend leggera e senza un browser headless.

Sentry + slog

Errori e trace vanno a Sentry, i log sono JSON strutturato prodotto dalla libreria standard e i worker espongono metriche nel formato testuale di Prometheus.

Perché

Poche parti in movimento da gestire, e ogni errore arriva con il suo contesto.

App e CLI

Un unico client Vue serve il web e viene impacchettato da Tauri per desktop e dispositivi mobili. Il client da riga di comando usa la stessa API pubblica delle app.

Vue 3 + TypeScript Vue 3.5 · TS 5.9 · Pinia 3

Un unico client con 118 componenti single-file, store Pinia, vue-router e vue-i18n in 23 lingue dell’interfaccia, testato con Vitest.

Perché

Un modello a componenti maturo e leggibile e un TypeScript rigoroso rendono gestibile un client di grandi dimensioni per un team molto piccolo.

Vite + Tailwind CSS Vite 8 · Tailwind 4

Lo strumento di build e il livello di stile: Tailwind CSS 4 con un tema chiaro e uno scuro.

Perché

Build veloci e design token che seguono la stessa palette documentata del sito web.

Tauri 2.10

Impacchetta lo stesso client web per macOS, Windows, Linux, iOS e Android, con notifiche native, deep link e aggiornamenti desktop firmati.

Perché

Un’unica interfaccia ovunque, usando la webview di sistema invece di includere un motore browser in ogni app.

Client Connect generati connect-web 2.1 · protobuf-es 2

Client TypeScript generati dal Protobuf del backend e copiati nell’app web. Non vengono mai modificati a mano.

Perché

Una modifica al contratto diventa un errore di tipo nel client anziché una sorpresa in produzione.

centrifuge-js + livekit-client 5.7 · 2.20

Le librerie client per il realtime di Centrifugo e le chiamate LiveKit.

Perché

Riconnessione, recupero e gestione dei media provengono dagli stessi progetti che sviluppano i server.

TipTap 3.22

L’editor dei messaggi, con menzioni, link e blocchi di codice con evidenziazione della sintassi.

Perché

Un editor strutturato invece di una fragile manipolazione di stringhe.

hansa CLI Go 1.26 · Cobra

Un client da riga di comando stateless per persone, script e agenti LLM. Output JSON predefinito, credenziali nel portachiavi del sistema operativo e checksum delle release firmati con Minisign.

Perché

Usa la stessa API pubblica delle app. I suoi contratti Protobuf sono copiati dal backend e bloccati con hash SHA-256, così qualsiasi divergenza viene rilevata in CI.

Sito web, fatturazione e registro

Laravel gestisce il sito pubblico, la documentazione per i clienti, il checkout, gli abbonamenti e il registro centrale degli spazi di lavoro. Crea uno spazio di lavoro chiamando il backend Go tramite HTTP autenticato, senza codice condiviso né code condivise.

Laravel + PHP Laravel 12 · PHP 8.5

Il sito web pubblico, la documentazione per i clienti, il checkout, gli abbonamenti, i coupon, gli avvisi del ciclo di vita e il registro centrale degli spazi di lavoro e dei domini.

Perché

Fatturazione, e-mail, pianificazione, code e moduli sono i punti di forza di Laravel. La chat resta in Go, e il confine tra le due parti è un’unica interfaccia HTTP autenticata.

FrankenPHP 1.13

L’application server PHP all’interno dell’immagine container, costruito su un’immagine di base condivisa che fissa PHP, le sue estensioni e gli strumenti tramite digest.

Perché

Un solo processo serve l’applicazione, e ricompilare lo stesso commit produce lo stesso ambiente di esecuzione.

Blade + Alpine.js + Tailwind CSS Alpine 3.15 · Tailwind 3.4 · Vite 7

Pagine renderizzate lato server con piccoli componenti Alpine.js, stilizzate con Tailwind CSS e impacchettate da Vite.

Perché

Le pagine di contenuto si caricano rapidamente senza distribuire un framework per single-page app.

22 lingue

Ogni pagina pubblica esiste in 22 lingue dell’UE, con URL con prefisso della lingua, link hreflang e una sitemap localizzata. Un test fallisce se a una lingua manca una chiave o se contiene testo in inglese.

Perché

Un prodotto europeo dovrebbe essere leggibile nella lingua dell’acquirente fin dalla prima pagina.

Creem

Checkout, imposte, fatture e abbonamenti, mantenuti sincronizzati tramite webhook firmati.

Perché

Pagamenti, imposte e fatturazione restano a un fornitore specializzato, mentre il sito web conserva una copia riconciliata di ogni abbonamento.

EmailLabs

E-mail transazionali e di servizio, come inviti, link per la password e avvisi.

Perché

Un fornitore e-mail dell’UE per un prodotto dell’UE.

Pest 4.4

Oltre 130 file di test coprono route, fatturazione, provisioning, traduzioni e SEO, inclusi test nel browser.

Perché

Test veloci e leggibili che vengono eseguiti a ogni modifica.

Piattaforma e operazioni

Produzione e preproduzione girano su IONOS in Germania. Ogni applicazione viene distribuita come immagine container con il proprio chart Helm e rilasciata tramite un job GitLab avviato manualmente.

IONOS Managed Kubernetes

Cluster di produzione e preproduzione, MariaDB gestito e Object Storage compatibile con S3, tutto gestito da un fornitore tedesco in Germania.

Perché

Un fornitore europeo soggetto alla giurisdizione dell’UE, non la region europea di un cloud non europeo.

Helm + Traefik

Ogni applicazione ha il proprio chart. Traefik instrada il traffico all’interno del cluster, e le migrazioni dei database degli spazi di lavoro vengono eseguite come hook prima di ogni rollout del backend.

Perché

Ogni deployment è versionato, ripetibile e facile da annullare.

Bunny.net

CDN, DNS e protezione DDoS davanti al cluster, oltre all’archiviazione per i backup cifrati.

Perché

Un’azienda europea gestisce l’edge e custodisce le copie di backup, così nessuno dei due dipende da un cloud non europeo.

Valkey + Sentinel + HAProxy Valkey 9.1

Tre repliche con failover tramite Sentinel e un proxy HAProxy che punta sempre al primario attuale. Supporta cache, sessioni, presenza e il broker realtime.

Perché

Un failover non richiede modifiche all’applicazione, perché ogni servizio continua a comunicare con lo stesso indirizzo.

restic 0.18

Backup cifrati dei database ogni 6 ore verso due sedi nell’UE, con controlli di integrità settimanali e un’esercitazione di ripristino mensile automatizzata.

Perché

Un backup conta solo quando un ripristino ne ha dimostrato la validità.

GitLab CI

Test, build delle immagini e controlli dei chart Helm vengono eseguiti in CI. I deployment in preproduzione e in produzione sono job separati, avviati manualmente.

Perché

L’automazione svolge il lavoro ripetitivo; una persona decide quando qualcosa arriva ai clienti.

Attorno al prodotto

Gli strumenti che rendono un’azienda di una sola persona osservabile, raggiungibile e comprensibile.

Cloudflare Workers + D1

Una pagina di stato esterna che controlla l’app e il sito web ogni cinque minuti e registra gli incidenti.

Perché

La disponibilità viene misurata dall’esterno dell’infrastruttura che descrive.

Umami 3.2

Analisi web self-hosted che entra in funzione solo dopo che il visitatore ha espresso la propria scelta sul consenso.

Perché

I dati dei visitatori restano sull’infrastruttura di HansaChat invece di alimentare una rete pubblicitaria.

Remotion 4.0

I video del prodotto vengono registrati dall’applicazione reale tramite il test runner end-to-end e composti nel codice con una voce fuori campo generata dall’IA.

Perché

Quando l’interfaccia cambia, il video viene renderizzato di nuovo invece di essere girato di nuovo.

TwentyCRM + WireGuard

Un CRM self-hosted raggiungibile solo tramite una VPN privata.

Perché

I dati commerciali non sono in alcun modo esposti sull’internet pubblico.

Pratiche di ingegneria

Le abitudini che permettono a una sola persona di rilasciare un prodotto multi-tenant senza un team separato di QA o di operazioni.

I contratti sono generati, mai scritti a mano

Protobuf è l’unica fonte per il server Go, i client TypeScript e la CLI. I generatori sono fissati a versioni esatte, e la CLI registra l’hash di ogni file di contratto che utilizza.

Le migrazioni tengono un registro

Ogni database di spazio di lavoro registra quali migrazioni ha applicato. Un hook di deployment applica solo quelle mancanti e ricontrolla dopo il rollout. Il sito web conserva le sue migrazioni di base originali, così i database esistenti non le eseguono mai due volte.

Test end-to-end su uno stack isolato

Un solo comando avvia i database, NATS, Valkey, Centrifugo e l’object storage su porte libere, compila i binari Go, avvia l’app web ed esegue 70 specifiche Playwright con uno spazio di lavoro nuovo per ogni test.

Test a ogni livello

478 funzioni di test Go, inclusi test di isolamento tra due spazi di lavoro, 109 file Vitest nel client e oltre 130 file Pest sul sito web.

Paletti di sicurezza in CI

Controlli di formattazione, un limite di 1.000 righe per file Go e test dei chart Helm vengono eseguiti in CI accanto alle suite di test.

Approvazione manuale dei deployment

La CI compila e testa in automatico, ma i deployment in preproduzione e in produzione sono job manuali separati. In produzione viene rilasciato un tag di release creato solo dopo il merge della modifica.

Backup verificati con ripristini

Ogni esecuzione di backup è monitorata, e un’esercitazione automatizzata ripristina i database ogni mese e convalida tabelle e numero di righe.

Un unico design system

Il sito web e l’app condividono una palette documentata, una scala tipografica e regole per i componenti, con un tema chiaro e uno scuro nell’app.

Assistito dall’IA, approvato da una persona

Gli agenti di programmazione IA lavorano a partire da un file di istruzioni presente in ogni repository, che rimanda a un repository centrale di documentazione tecnica. I flussi di lavoro ripetibili, come l’esecuzione end-to-end, sono impacchettati come skill per agenti. Ogni modifica deve comunque superare gli stessi test, e i deployment restano manuali.

Gestione della sicurezza in preparazione

HansaChat si sta preparando alla certificazione ISO/IEC 27001 con un registro dei rischi, un registro delle evidenze e un registro delle decisioni. Oggi non è certificato.

Cosa dichiara questa pagina — e cosa no

Tutto quanto sopra descrive ciò che è implementato oggi ed è stato contato nei repository del codice sorgente. HansaChat non dichiara alcuna certificazione di sicurezza. Il triage dei messaggi è in fase pilota, e le notifiche push per le app chiuse non sono ancora attive.

Domande sull’architettura?

Gli ingegneri che valutano HansaChat ricevono risposte dirette dalla persona che lo ha costruito.

Scrivi allo sviluppatore