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
- Il client chiama il servizio dei messaggi tramite ConnectRPC.
- L’API accetta la richiesta solo dopo che NATS JetStream ha memorizzato il comando in modo durevole.
- Un worker scrive il messaggio e un evento di outbox nel database dello spazio di lavoro in un’unica transazione.
- Il relay dell’outbox pubblica l’evento confermato su NATS e Centrifugo.
- 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.