Stack technique
HansaChat est un chat d’entreprise européen doté d’une couche opérationnelle pour les équipes de terrain, conçu, développé et exploité par une seule personne. Cette page présente la technologie de chaque composant et la raison de ce choix.
Versions et chiffres vérifiés en octobre 2026.
Comptés dans les dépôts
- services ConnectRPC totalisant 179 RPC, tous définis en Protobuf
- 18
- binaires Go issus d’une seule base de code : API, worker, relais d’outbox, administration
- 4
- plateformes à partir d’un seul client : web, macOS, Windows, Linux, iOS, Android
- 6
- langues sur le site web public
- 22
- langues d’interface dans l’application
- 23
- scénarios Playwright de bout en bout sur une stack isolée
- 70
Comment les éléments s’articulent
Trois applications partagent une même couche edge et un même cluster. Le site web gère la facturation et le registre des espaces de travail, le backend Go gère tout ce qui se passe à l’intérieur d’un espace de travail, et l’application web communique avec le backend via des clients ConnectRPC générés.
Clients
Navigateur
Site web et application web
Tauri
Enveloppes bureau et mobile
hansa CLI
Scripts et agents
Edge
Bunny.net CDN
TLS, cache, protection DDoS
IONOS Managed Kubernetes, Allemagne
Traefik
Ingress pour chaque application
Application web Vue + Vite
Build Vue statique
API du chat
Go avec ConnectRPC
- Worker
- Relais d’outbox
Site web Laravel + FrankenPHP
Facturation, registre, provisionnement
NATS JetStream
Commandes et événements durables
Centrifugo
Diffusion WebSocket
Valkey Sentinel + HAProxy
Cache, présence, sessions
LiveKit
Flux média des appels
Données gérées chez IONOS
MariaDB
Une base de données par espace de travail, plus un registre central
Stockage objet S3
Fichiers et avatars
Services externes
ElevenLabs · LLM · Clef
Transcription, traduction, tri
Creem · EmailLabs
Paiements et e-mails
Hors du cluster
Cloudflare Workers D1
Vérifications de disponibilité externes
Bunny Storage restic
Sauvegardes chiffrées à Francfort et à Stockholm
Le parcours d’un message
- Le client appelle le service de messagerie via ConnectRPC.
- L’API n’accepte la requête qu’une fois la commande stockée de manière durable par NATS JetStream.
- Un worker écrit le message et un événement d’outbox dans la base de données de l’espace de travail, au sein d’une seule transaction.
- Le relais d’outbox publie l’événement validé vers NATS et Centrifugo.
- Chaque client ouvert le reçoit via WebSocket ; après une interruption, les clients rechargent l’état de référence depuis l’API.
Backend du chat
Tout ce qui se passe à l’intérieur d’un espace de travail s’exécute en Go : messages, canaux, fichiers, appels, temps réel, imports et le module opérationnel dédié au nettoyage. Le site web ne touche jamais aux données des espaces de travail.
- Go 1.26
-
Quatre binaires issus d’une base de code modulaire : l’API, le worker de messages, le relais d’outbox et une commande d’administration protégée. Ils sont livrés sous forme de binaires statiques dans une seule image légère.
Pourquoi
Une bibliothèque standard solide, des performances prévisibles et une concurrence simple conviennent à un backend composé de workers à longue durée de vie. Un seul langage pour tout le cœur de l’espace de travail permet à une seule personne de le maintenir.
- ConnectRPC + Protobuf connect-go 1.20 · buf 1.71
-
18 services et 179 RPC sont définis en Protobuf. buf génère le serveur Go et les clients TypeScript avec des plugins locaux, si bien qu’aucun schéma ne quitte la machine.
Pourquoi
Un seul contrat sert les clients web, bureau, mobile et en ligne de commande. Aucun chemin HTTP écrit à la main ni analyse manuelle des réponses, et une modification du contrat se manifeste par une erreur de compilation plutôt que par une panne à l’exécution.
- Une base de données par espace de travail MariaDB · sqlc
-
Chaque espace de travail dispose de sa propre base de données MariaDB physique. L’API identifie l’espace de travail à partir de son domaine et ouvre le pool correspondant ; les workers l’identifient à nouveau eux-mêmes et ne font jamais confiance à un nom de base de données reçu dans un message de file d’attente. Les requêtes sont du SQL simple compilé en Go typé avec sqlc.
Pourquoi
L’isolation est structurelle, et non un filtre ajouté à chaque requête. L’export, l’import, la restauration et la suppression se font par entreprise.
- NATS JetStream 2.10
-
Des streams durables pour les commandes, les tâches et les événements, ainsi qu’un stream de lettres mortes. Les écritures de messages s’exécutent dans 64 partitions ordonnées.
Pourquoi
Un message n’est accepté qu’après un accusé de réception durable. Les messages d’un même canal restent dans l’ordre, tandis que les canaux indépendants sont traités en parallèle.
- Outbox transactionnelle
-
Les lignes métier et l’événement sortant sont validés dans la même transaction. Un relais publie les événements validés vers NATS et Centrifugo, dédupliqués par identifiant d’événement, et consigne les échecs pour les relancer.
Pourquoi
Aucun événement perdu ni fantôme lorsqu’un processus s’arrête entre l’écriture en base et la publication.
- Centrifugo v5
-
Diffusion WebSocket des messages, de la présence, des indicateurs de saisie et de l’état des appels. Les clients s’abonnent avec des jetons de courte durée propres à chaque canal, que l’API n’émet qu’après avoir vérifié l’appartenance à l’espace de travail.
Pourquoi
Un serveur temps réel dédié tient les connexions de longue durée à l’écart du processus de l’API, et chaque jeton désigne à la fois l’espace de travail et l’utilisateur, de sorte que des identités issues de bases distinctes ne peuvent pas entrer en collision.
- Stockage objet compatible S3 aws-sdk-go-v2
-
Les fichiers et les avatars sont stockés dans l’Object Storage d’IONOS dans l’UE et distribués via des liens signés de courte durée.
Pourquoi
Le stockage des fichiers évolue indépendamment des bases de données et il est chiffré au repos côté serveur.
- LiveKit 1.9
-
Un serveur média WebRTC auto-hébergé pour les appels en messages directs et les appels de canal centrés sur l’audio, avec caméra et partage d’écran.
Pourquoi
Open source et auto-hébergeable, si bien que les flux média des appels transitent par une infrastructure exploitée par HansaChat.
- ElevenLabs Scribe
-
Reconnaissance vocale pour les messages vocaux. La transcription est rattachée au message, consultable par la recherche et traduisible comme n’importe quel texte.
Pourquoi
Les équipes de terrain parlent plus qu’elles n’écrivent.
- Traduction par LLM
-
Traduction propre à chaque lecteur via une API compatible OpenAI. Chaque message est traduit à la demande, mis en cache une seule fois par langue cible et ignoré lorsque le lecteur partage déjà la langue.
Pourquoi
Une équipe multilingue travaille dans une même conversation tandis que chaque membre lit dans sa propre langue. Le fournisseur reste remplaçable derrière une interface unique.
- Cloudflare Clef
-
Un modèle de décision classe les messages opérationnels par catégorie, urgence et niveau de confiance. Il renvoie des probabilités pour des questions fixes, pas du texte généré. Actuellement en phase pilote.
Pourquoi
Il n’y a aucune sortie en texte libre à analyser. Les responsables voient ce qui demande leur attention ; la suite à donner reste toujours une décision humaine.
- go-pdf 0.9
-
Les feuilles de temps et les rapports d’intervention au format A4 sont générés sur le serveur.
Pourquoi
Une bibliothèque écrite entièrement en Go garde l’image du backend légère et sans navigateur headless.
- Sentry + slog
-
Les erreurs et les traces partent vers Sentry, les logs sont du JSON structuré produit par la bibliothèque standard, et les workers exposent des métriques au format texte de Prometheus.
Pourquoi
Peu de pièces mobiles à exploiter, et chaque défaillance arrive avec son contexte.
Applications et CLI
Un seul client Vue sert le web et est empaqueté par Tauri pour le bureau et le mobile. Le client en ligne de commande utilise la même API publique que les applications.
- Vue 3 + TypeScript Vue 3.5 · TS 5.9 · Pinia 3
-
Un client unique avec 118 composants monofichiers, des stores Pinia, vue-router et vue-i18n en 23 langues d’interface, testé avec Vitest.
Pourquoi
Un modèle de composants mature et lisible ainsi qu’un TypeScript strict rendent un gros client maîtrisable pour une très petite équipe.
- Vite + Tailwind CSS Vite 8 · Tailwind 4
-
L’outil de build et la couche de style : Tailwind CSS 4 avec un thème clair et un thème sombre.
Pourquoi
Des builds rapides et des design tokens qui suivent la même palette documentée que le site web.
- Tauri 2.10
-
Empaquette le même client web pour macOS, Windows, Linux, iOS et Android, avec notifications natives, liens profonds et mises à jour signées sur ordinateur.
Pourquoi
Une seule interface partout, en s’appuyant sur la webview du système au lieu d’embarquer un moteur de navigateur dans chaque application.
- Clients Connect générés connect-web 2.1 · protobuf-es 2
-
Des clients TypeScript générés à partir du Protobuf du backend et copiés dans l’application web. Ils ne sont jamais modifiés à la main.
Pourquoi
Une modification du contrat devient une erreur de type dans le client plutôt qu’une surprise en production.
- centrifuge-js + livekit-client 5.7 · 2.20
-
Les bibliothèques clientes pour le temps réel de Centrifugo et les appels LiveKit.
Pourquoi
La reconnexion, la reprise et la gestion des médias proviennent des projets qui développent les serveurs.
- TipTap 3.22
-
L’éditeur de messages, avec mentions, liens et blocs de code avec coloration syntaxique.
Pourquoi
Un éditeur structuré plutôt qu’une manipulation fragile de chaînes de caractères.
- hansa CLI Go 1.26 · Cobra
-
Un client en ligne de commande sans état pour les personnes, les scripts et les agents LLM. Sortie JSON par défaut, identifiants dans le trousseau du système d’exploitation et sommes de contrôle des versions signées avec Minisign.
Pourquoi
Il utilise la même API publique que les applications. Ses contrats Protobuf sont copiés depuis le backend et verrouillés par des empreintes SHA-256, de sorte que toute divergence est détectée en CI.
Site web, facturation et registre
Laravel fait tourner le site public, la documentation client, le paiement, les abonnements et le registre central des espaces de travail. Il crée un espace de travail en appelant le backend Go via HTTP authentifié, sans code partagé ni files d’attente partagées.
- Laravel + PHP Laravel 12 · PHP 8.5
-
Le site web public, la documentation client, le paiement, les abonnements, les coupons, les notifications de cycle de vie et le registre central des espaces de travail et des domaines.
Pourquoi
La facturation, les e-mails, la planification, les files d’attente et les formulaires sont les points forts de Laravel. Le chat reste en Go, et la frontière entre les deux est une seule interface HTTP authentifiée.
- FrankenPHP 1.13
-
Le serveur d’applications PHP intégré à l’image de conteneur, construit sur une image de base partagée qui épingle PHP, ses extensions et ses outils par digest.
Pourquoi
Un seul processus sert l’application, et reconstruire le même commit produit le même environnement d’exécution.
- Blade + Alpine.js + Tailwind CSS Alpine 3.15 · Tailwind 3.4 · Vite 7
-
Des pages rendues côté serveur avec de petits composants Alpine.js, stylées avec Tailwind CSS et regroupées par Vite.
Pourquoi
Les pages de contenu se chargent rapidement sans embarquer de framework d’application monopage.
- 22 langues
-
Chaque page publique existe dans 22 langues de l’UE, avec des URL préfixées par la langue, des liens hreflang et un sitemap localisé. Un test échoue si une langue omet une clé ou affiche du texte en anglais.
Pourquoi
Un produit européen doit être lisible dans la langue de l’acheteur dès la première page.
- Creem
-
Paiement, taxes, factures et abonnements, synchronisés via des webhooks signés.
Pourquoi
Le paiement, les taxes et la facturation restent confiés à un prestataire spécialisé, tandis que le site web conserve une copie rapprochée de chaque abonnement.
- EmailLabs
-
E-mails transactionnels et de service, comme les invitations, les liens de mot de passe et les notifications.
Pourquoi
Un fournisseur d’e-mail européen pour un produit européen.
- Pest 4.4
-
Plus de 130 fichiers de tests couvrent les routes, la facturation, le provisionnement, les traductions et le SEO, y compris des tests dans le navigateur.
Pourquoi
Des tests rapides et lisibles, exécutés à chaque modification.
Plateforme et exploitation
La production et la préproduction tournent chez IONOS en Allemagne. Chaque application est livrée sous forme d’image de conteneur avec son propre chart Helm et déployée par un job GitLab déclenché manuellement.
- IONOS Managed Kubernetes
-
Clusters de production et de préproduction, MariaDB géré et Object Storage compatible S3, le tout exploité par un fournisseur allemand en Allemagne.
Pourquoi
Un fournisseur européen soumis au droit de l’UE, et non la région européenne d’un cloud non européen.
- Helm + Traefik
-
Chaque application est livrée avec son propre chart. Traefik route le trafic à l’intérieur du cluster, et les migrations des bases de données des espaces de travail s’exécutent sous forme de hook avant chaque déploiement du backend.
Pourquoi
Chaque déploiement est versionné, reproductible et facile à annuler.
- Bunny.net
-
CDN, DNS et protection DDoS devant le cluster, ainsi que le stockage des sauvegardes chiffrées.
Pourquoi
Une entreprise européenne exploite la couche edge et conserve les copies de sauvegarde, si bien qu’aucune des deux ne dépend d’un cloud non européen.
- Valkey + Sentinel + HAProxy Valkey 9.1
-
Trois réplicas avec bascule gérée par Sentinel et un proxy HAProxy qui pointe toujours vers le primaire actuel. Il sert au cache, aux sessions, à la présence et au broker temps réel.
Pourquoi
Une bascule ne nécessite aucune modification de l’application, car chaque service continue de s’adresser à la même adresse.
- restic 0.18
-
Sauvegardes chiffrées des bases de données toutes les 6 heures vers deux sites dans l’UE, avec des vérifications d’intégrité hebdomadaires et un exercice de restauration mensuel automatisé.
Pourquoi
Une sauvegarde ne compte qu’une fois sa restauration prouvée.
- GitLab CI
-
Les tests, la construction des images et les vérifications des charts Helm s’exécutent en CI. Les déploiements en préproduction et en production sont des jobs distincts, déclenchés manuellement.
Pourquoi
L’automatisation se charge du travail répétitif ; une personne décide du moment où un changement atteint les clients.
Autour du produit
Les outils qui permettent à une entreprise d’une seule personne de rester observable, joignable et compréhensible.
- Cloudflare Workers + D1
-
Une page de statut externe qui vérifie l’application et le site web toutes les cinq minutes et consigne les incidents.
Pourquoi
La disponibilité est mesurée depuis l’extérieur de l’infrastructure qu’elle décrit.
- Umami 3.2
-
Une mesure d’audience auto-hébergée qui ne s’exécute qu’après que le visiteur a exprimé son choix de consentement.
Pourquoi
Les données des visiteurs restent sur l’infrastructure de HansaChat au lieu d’alimenter un réseau publicitaire.
- Remotion 4.0
-
Les vidéos du produit sont enregistrées à partir de l’application réelle par l’exécuteur de tests de bout en bout et montées par le code avec une voix off générée par IA.
Pourquoi
Quand l’interface change, la vidéo est de nouveau générée au lieu d’être tournée à nouveau.
- TwentyCRM + WireGuard
-
Un CRM auto-hébergé accessible uniquement via un VPN privé.
Pourquoi
Les données commerciales ne sont absolument pas exposées sur l’internet public.
Pratiques d’ingénierie
Les habitudes qui permettent à une seule personne de livrer un produit multi-locataire sans équipe QA ni équipe d’exploitation dédiée.
Les contrats sont générés, jamais écrits à la main
Protobuf est la source unique pour le serveur Go, les clients TypeScript et la CLI. Les générateurs sont épinglés à des versions exactes, et la CLI enregistre l’empreinte de chaque fichier de contrat qu’elle utilise.
Les migrations tiennent un registre
Chaque base de données d’espace de travail enregistre les migrations qu’elle a appliquées. Un hook de déploiement applique uniquement celles qui manquent et vérifie de nouveau après le déploiement. Le site web conserve ses migrations de base d’origine afin que les bases existantes ne les exécutent jamais deux fois.
Tests de bout en bout sur une stack isolée
Une seule commande démarre les bases de données, NATS, Valkey, Centrifugo et le stockage objet sur des ports libres, compile les binaires Go, lance l’application web et exécute 70 scénarios Playwright avec un espace de travail neuf pour chaque test.
Des tests à chaque couche
478 fonctions de test Go, dont des tests d’isolation entre deux espaces de travail, 109 fichiers Vitest dans le client et plus de 130 fichiers Pest sur le site web.
Garde-fous en CI
Vérifications de formatage, limite de 1 000 lignes par fichier Go et tests des charts Helm s’exécutent en CI aux côtés des suites de tests.
Validation manuelle des déploiements
La CI compile et teste automatiquement, mais les déploiements en préproduction et en production sont des jobs manuels distincts. La production déploie un tag de version qui n’est créé qu’après la fusion du changement.
Des sauvegardes prouvées par des restaurations
Chaque exécution de sauvegarde est surveillée, et un exercice automatisé restaure les bases de données chaque mois puis valide les tables et le nombre de lignes.
Un seul design system
Le site web et l’application partagent une palette documentée, une échelle typographique et des règles de composants, avec un thème clair et un thème sombre dans l’application.
Assisté par l’IA, validé par un humain
Les agents de programmation IA travaillent à partir d’un fichier d’instructions présent dans chaque dépôt, qui renvoie vers un dépôt central de documentation d’ingénierie. Les workflows répétables, comme l’exécution de bout en bout, sont empaquetés sous forme de skills d’agent. Chaque modification passe toujours les mêmes tests, et les déploiements restent manuels.
Management de la sécurité en préparation
HansaChat se prépare à la certification ISO/IEC 27001 avec un registre des risques, un registre des preuves et un journal des décisions. HansaChat n’est pas certifié à ce jour.
Ce que cette page affirme — et ce qu’elle n’affirme pas
Tout ce qui précède décrit ce qui est mis en œuvre aujourd’hui et a été compté dans les dépôts de code source. HansaChat ne revendique aucune certification de sécurité. Le tri des messages est en phase pilote, et les notifications push pour les applications fermées ne sont pas encore en service.
Des questions sur l’architecture ?
Les ingénieurs qui évaluent HansaChat obtiennent des réponses directes de la personne qui l’a construit.