Stos technologiczny
HansaChat to europejski czat firmowy z warstwą operacyjną dla zespołów terenowych, zaprojektowany, zbudowany i utrzymywany przez jedną osobę. Ta strona pokazuje, z czego zbudowana jest każda część i dlaczego ją wybrano.
Wersje i liczby zweryfikowano w październiku 2026 r.
Policzone w repozytoriach
- usług ConnectRPC ze 179 wywołaniami RPC, wszystkie zdefiniowane w Protobuf
- 18
- pliki binarne Go z jednej bazy kodu: API, worker, przekaźnik outboxa, narzędzie administracyjne
- 4
- platform z jednego klienta: web, macOS, Windows, Linux, iOS, Android
- 6
- języki na publicznej stronie internetowej
- 22
- języki interfejsu w aplikacji
- 23
- specyfikacji end-to-end w Playwright na odizolowanym środowisku
- 70
Jak elementy do siebie pasują
Trzy aplikacje współdzielą jedną warstwę brzegową i jeden klaster. Strona internetowa odpowiada za rozliczenia i rejestr przestrzeni roboczych, backend w Go za wszystko, co dzieje się wewnątrz przestrzeni roboczej, a aplikacja webowa komunikuje się z backendem przez wygenerowane klienty ConnectRPC.
Klienty
Przeglądarka
Strona internetowa i aplikacja webowa
Tauri
Powłoki desktopowe i mobilne
hansa CLI
Skrypty i agenci
Warstwa brzegowa
Bunny.net CDN
TLS, cache, ochrona przed DDoS
IONOS Managed Kubernetes, Niemcy
Traefik
Ingress dla każdej aplikacji
Aplikacja webowa Vue + Vite
Statyczny build Vue
API czatu
Go z ConnectRPC
- Worker
- Przekaźnik outboxa
Strona internetowa Laravel + FrankenPHP
Rozliczenia, rejestr, provisioning
NATS JetStream
Trwałe polecenia i zdarzenia
Centrifugo
Rozsyłanie przez WebSocket
Valkey Sentinel + HAProxy
Cache, obecność, sesje
LiveKit
Media połączeń
Zarządzane dane w IONOS
MariaDB
Jedna baza danych na przestrzeń roboczą plus centralny rejestr
Magazyn obiektów S3
Pliki i awatary
Usługi zewnętrzne
ElevenLabs · LLM · Clef
Transkrypcja, tłumaczenie, triaż
Creem · EmailLabs
Płatności i e-mail
Poza klastrem
Cloudflare Workers D1
Zewnętrzne kontrole dostępności
Bunny Storage restic
Zaszyfrowane kopie zapasowe we Frankfurcie i Sztokholmie
Droga jednej wiadomości
- Klient wywołuje usługę wiadomości przez ConnectRPC.
- API przyjmuje żądanie dopiero wtedy, gdy NATS JetStream trwale zapisze polecenie.
- Worker zapisuje wiadomość i zdarzenie outboxa w bazie danych przestrzeni roboczej w jednej transakcji.
- Przekaźnik outboxa publikuje zatwierdzone zdarzenie w NATS i Centrifugo.
- Każdy otwarty klient odbiera je przez WebSocket; po przerwie klienty ponownie wczytują wiarygodny stan z API.
Backend czatu
Wszystko, co dzieje się wewnątrz przestrzeni roboczej, działa w Go: wiadomości, kanały, pliki, połączenia, komunikacja w czasie rzeczywistym, importy oraz pakiet operacyjny dla firm sprzątających. Strona internetowa nigdy nie dotyka danych przestrzeni roboczych.
- Go 1.26
-
Cztery pliki binarne z jednej modułowej bazy kodu: API, worker wiadomości, przekaźnik outboxa i zabezpieczone polecenie administracyjne. Są dostarczane jako statyczne pliki binarne w jednym niewielkim obrazie.
Dlaczego
Solidna biblioteka standardowa, przewidywalna wydajność i prosta współbieżność pasują do backendu złożonego z długo działających workerów. Jeden język dla całego rdzenia przestrzeni roboczej sprawia, że jedna osoba może go utrzymywać.
- ConnectRPC + Protobuf connect-go 1.20 · buf 1.71
-
18 usług i 179 wywołań RPC zdefiniowano w Protobuf. buf generuje serwer w Go i klienty w TypeScript za pomocą lokalnych wtyczek, więc żaden schemat nie opuszcza maszyny.
Dlaczego
Jeden kontrakt obsługuje klienty webowe, desktopowe, mobilne i wiersza poleceń. Nie ma ręcznie pisanych ścieżek HTTP ani ręcznego parsowania odpowiedzi, a zmiana kontraktu ujawnia się jako błąd kompilacji, a nie awaria w czasie działania.
- Jedna baza danych na przestrzeń roboczą MariaDB · sqlc
-
Każda przestrzeń robocza ma własną fizyczną bazę danych MariaDB. API ustala przestrzeń roboczą na podstawie jej domeny i otwiera odpowiednią pulę połączeń; workery ustalają ją ponownie samodzielnie i nigdy nie ufają nazwie bazy danych z wiadomości w kolejce. Zapytania to zwykły SQL kompilowany przez sqlc do typowanego kodu Go.
Dlaczego
Izolacja wynika ze struktury, a nie z filtra w każdym zapytaniu. Eksport, import, odtwarzanie i usuwanie działają dla każdej firmy osobno.
- NATS JetStream 2.10
-
Trwałe strumienie dla poleceń, zadań i zdarzeń oraz strumień dead-letter dla komunikatów, których nie udało się przetworzyć. Zapisy wiadomości odbywają się w 64 uporządkowanych partycjach.
Dlaczego
Wiadomość jest przyjmowana dopiero po trwałym potwierdzeniu. Wiadomości w jednym kanale zachowują kolejność, a niezależne kanały są przetwarzane równolegle.
- Transakcyjny outbox
-
Wiersze domenowe i wychodzące zdarzenie są zatwierdzane w tej samej transakcji. Przekaźnik publikuje zatwierdzone zdarzenia w NATS i Centrifugo, usuwając duplikaty na podstawie identyfikatora zdarzenia, i rejestruje błędy do ponowienia.
Dlaczego
Żadnych utraconych ani fantomowych zdarzeń, gdy proces zatrzyma się między zapisem do bazy danych a publikacją.
- Centrifugo v5
-
Dostarczanie przez WebSocket wiadomości, statusu obecności, wskaźników pisania i stanu połączeń. Klienty subskrybują kanały za pomocą krótkotrwałych tokenów wydawanych osobno dla każdego kanału, które API wystawia dopiero po sprawdzeniu członkostwa w przestrzeni roboczej.
Dlaczego
Dedykowany serwer czasu rzeczywistego utrzymuje długotrwałe połączenia poza procesem API, a każdy token wskazuje zarówno przestrzeń roboczą, jak i użytkownika, więc tożsamości z różnych baz danych nie mogą ze sobą kolidować.
- Magazyn obiektów zgodny z S3 aws-sdk-go-v2
-
Pliki i awatary są przechowywane w IONOS Object Storage w UE i udostępniane przez krótkotrwałe podpisane linki.
Dlaczego
Magazyn plików skaluje się niezależnie od baz danych i jest szyfrowany w spoczynku po stronie serwera.
- LiveKit 1.9
-
Samodzielnie hostowany serwer mediów WebRTC do połączeń w wiadomościach bezpośrednich oraz połączeń w kanałach nastawionych przede wszystkim na dźwięk, z kamerą i udostępnianiem ekranu.
Dlaczego
To oprogramowanie open source, które można hostować samodzielnie, więc media połączeń przechodzą przez infrastrukturę obsługiwaną przez HansaChat.
- ElevenLabs Scribe
-
Zamiana mowy na tekst dla wiadomości głosowych. Transkrypcja jest dołączana do wiadomości, można ją przeszukiwać i tłumaczyć jak każdy inny tekst.
Dlaczego
Ekipy w terenie częściej mówią, niż piszą.
- Tłumaczenie przez LLM
-
Tłumaczenie dla każdego czytelnika osobno przez API zgodne z OpenAI. Każda wiadomość jest tłumaczona na żądanie, zapisywana w cache raz dla każdego języka docelowego i pomijana, gdy czytelnik posługuje się już tym językiem.
Dlaczego
Wielojęzyczna ekipa pracuje w jednej rozmowie, a każdy jej członek czyta we własnym języku. Dostawcę wciąż można wymienić, bo stoi za jednym interfejsem.
- Cloudflare Clef
-
Model decyzyjny klasyfikuje wiadomości operacyjne według kategorii, pilności i poziomu pewności. Zwraca prawdopodobieństwa dla stałych pytań, a nie generowany tekst. Obecnie w fazie pilotażowej.
Dlaczego
Nie ma swobodnego tekstu do parsowania. Kierownicy widzą, co wymaga uwagi; decyzja o działaniu zawsze należy do człowieka.
- go-pdf 0.9
-
Karty czasu pracy i raporty z wykonanych usług w formacie A4 są generowane na serwerze.
Dlaczego
Biblioteka napisana w całości w Go sprawia, że obraz backendu pozostaje mały i nie wymaga przeglądarki headless.
- Sentry + slog
-
Błędy i ślady trafiają do Sentry, logi to ustrukturyzowany JSON z biblioteki standardowej, a workery udostępniają metryki w tekstowym formacie Prometheusa.
Dlaczego
Niewiele ruchomych części do utrzymania, a każdy błąd trafia wraz ze swoim kontekstem.
Aplikacje i CLI
Jeden klient w Vue obsługuje wersję webową, a Tauri pakuje go na komputery i urządzenia mobilne. Klient wiersza poleceń korzysta z tego samego publicznego API co aplikacje.
- Vue 3 + TypeScript Vue 3.5 · TS 5.9 · Pinia 3
-
Jeden klient ze 118 komponentami jednoplikowymi, store’ami Pinia, vue-router i vue-i18n w 23 językach interfejsu, testowany za pomocą Vitest.
Dlaczego
Dojrzały, czytelny model komponentów i rygorystyczny TypeScript sprawiają, że duży klient pozostaje w zasięgu bardzo małego zespołu.
- Vite + Tailwind CSS Vite 8 · Tailwind 4
-
Narzędzie do budowania i warstwa stylów: Tailwind CSS 4 z jasnym i ciemnym motywem.
Dlaczego
Szybkie buildy i tokeny projektowe zgodne z tą samą udokumentowaną paletą co strona internetowa.
- Tauri 2.10
-
Pakuje tego samego klienta webowego na macOS, Windows, Linux, iOS i Android, z natywnymi powiadomieniami, deep linkami i podpisanymi aktualizacjami na komputery.
Dlaczego
Jeden interfejs wszędzie, z wykorzystaniem systemowego webview zamiast dołączania silnika przeglądarki do każdej aplikacji.
- Generowane klienty Connect connect-web 2.1 · protobuf-es 2
-
Klienty w TypeScript generowane z definicji Protobuf backendu i kopiowane do aplikacji webowej. Nigdy nie są edytowane ręcznie.
Dlaczego
Zmiana kontraktu staje się błędem typów w kliencie, a nie niespodzianką na produkcji.
- centrifuge-js + livekit-client 5.7 · 2.20
-
Biblioteki klienckie do komunikacji w czasie rzeczywistym przez Centrifugo i do połączeń LiveKit.
Dlaczego
Ponowne łączenie, odtwarzanie stanu i obsługa mediów pochodzą od projektów, które tworzą same serwery.
- TipTap 3.22
-
Edytor wiadomości ze wzmiankami, linkami i blokami kodu z podświetlaniem składni.
Dlaczego
Ustrukturyzowany edytor zamiast kruchej obróbki ciągów znaków.
- hansa CLI Go 1.26 · Cobra
-
Bezstanowy klient wiersza poleceń dla ludzi, skryptów i agentów LLM. Domyślnie wynik w formacie JSON, dane uwierzytelniające w pęku kluczy systemu operacyjnego oraz sumy kontrolne wydań podpisane za pomocą Minisign.
Dlaczego
Korzysta z tego samego publicznego API co aplikacje. Jego kontrakty Protobuf są kopiowane z backendu i przypięte skrótami SHA-256, więc każda rozbieżność zostaje wykryta w CI.
Strona internetowa, rozliczenia i rejestr
Laravel obsługuje publiczną stronę, dokumentację dla klientów, proces zakupu, subskrypcje oraz centralny rejestr przestrzeni roboczych. Tworzy przestrzeń roboczą, wywołując backend w Go przez uwierzytelniony HTTP, bez współdzielonego kodu i bez współdzielonych kolejek.
- Laravel + PHP Laravel 12 · PHP 8.5
-
Publiczna strona internetowa, dokumentacja dla klientów, proces zakupu, subskrypcje, kupony, powiadomienia o cyklu życia oraz centralny rejestr przestrzeni roboczych i domen.
Dlaczego
Rozliczenia, poczta, harmonogramy, kolejki i formularze to najmocniejsze strony Laravela. Czat pozostaje w Go, a granicą między nimi jest jeden uwierzytelniony interfejs HTTP.
- FrankenPHP 1.13
-
Serwer aplikacji PHP wewnątrz obrazu kontenera, zbudowany na współdzielonym obrazie bazowym, który przypina PHP, jego rozszerzenia i narzędzia po skrócie (digest).
Dlaczego
Jeden proces obsługuje aplikację, a ponowne zbudowanie tego samego commita daje to samo środowisko uruchomieniowe.
- Blade + Alpine.js + Tailwind CSS Alpine 3.15 · Tailwind 3.4 · Vite 7
-
Strony renderowane po stronie serwera z niewielkimi komponentami Alpine.js, stylowane za pomocą Tailwind CSS i budowane przez Vite.
Dlaczego
Strony z treścią ładują się szybko bez dostarczania frameworka aplikacji jednostronicowej.
- 22 języki
-
Każda publiczna strona istnieje w 22 językach UE, z adresami URL poprzedzonymi kodem języka, linkami hreflang i zlokalizowaną mapą witryny. Test kończy się niepowodzeniem, jeśli w którymkolwiek języku brakuje klucza lub pojawia się tekst po angielsku.
Dlaczego
Europejski produkt powinien być czytelny w języku kupującego od pierwszej strony.
- Creem
-
Proces zakupu, podatki, faktury i subskrypcje, synchronizowane przez podpisane webhooki.
Dlaczego
Płatności, podatki i fakturowanie pozostają w rękach wyspecjalizowanego dostawcy, a strona internetowa przechowuje uzgodnioną kopię każdej subskrypcji.
- EmailLabs
-
Poczta transakcyjna i serwisowa, taka jak zaproszenia, linki do ustawienia hasła i powiadomienia.
Dlaczego
Unijny dostawca poczty e-mail dla unijnego produktu.
- Pest 4.4
-
Ponad 130 plików testowych obejmuje trasy, rozliczenia, provisioning, tłumaczenia i SEO, w tym testy w przeglądarce.
Dlaczego
Szybkie, czytelne testy uruchamiane przy każdej zmianie.
Platforma i utrzymanie
Środowiska produkcyjne i przedprodukcyjne działają w IONOS w Niemczech. Każda aplikacja jest dostarczana jako obraz kontenera z własnym chartem Helm i wdrażana przez ręcznie uruchamiany job w GitLabie.
- IONOS Managed Kubernetes
-
Klastry produkcyjne i przedprodukcyjne, zarządzana MariaDB oraz Object Storage zgodny z S3, wszystko obsługiwane przez niemieckiego dostawcę w Niemczech.
Dlaczego
Europejski dostawca podlegający jurysdykcji UE, a nie europejski region chmury spoza Europy.
- Helm + Traefik
-
Każda aplikacja ma własny chart. Traefik kieruje ruchem wewnątrz klastra, a migracje baz danych przestrzeni roboczych uruchamiają się jako hook przed każdym wdrożeniem backendu.
Dlaczego
Każde wdrożenie jest wersjonowane, powtarzalne i łatwe do wycofania.
- Bunny.net
-
CDN, DNS i ochrona przed DDoS przed klastrem, a także magazyn na zaszyfrowane kopie zapasowe.
Dlaczego
Warstwę brzegową obsługuje i kopie zapasowe przechowuje europejska firma, więc żadna z tych rzeczy nie zależy od chmury spoza Europy.
- Valkey + Sentinel + HAProxy Valkey 9.1
-
Trzy repliki z przełączaniem awaryjnym przez Sentinel i proxy HAProxy, które zawsze wskazuje bieżący węzeł główny. Obsługuje cache, sesje, status obecności i broker czasu rzeczywistego.
Dlaczego
Przełączenie awaryjne nie wymaga zmian w aplikacji, ponieważ każda usługa nadal komunikuje się z tym samym adresem.
- restic 0.18
-
Zaszyfrowane kopie zapasowe baz danych co 6 godzin w dwóch lokalizacjach w UE, z cotygodniowymi kontrolami integralności i automatycznym comiesięcznym ćwiczeniem odtwarzania.
Dlaczego
Kopia zapasowa liczy się dopiero wtedy, gdy udowodniono, że da się ją odtworzyć.
- GitLab CI
-
Testy, budowanie obrazów i kontrole chartów Helm działają w CI. Wdrożenia na środowisko przedprodukcyjne i produkcyjne to osobne, ręcznie uruchamiane joby.
Dlaczego
Automatyzacja wykonuje powtarzalną pracę; człowiek decyduje, kiedy coś trafia do klientów.
Wokół produktu
Narzędzia, dzięki którym jednoosobowa firma pozostaje obserwowalna, osiągalna i zrozumiała.
- Cloudflare Workers + D1
-
Zewnętrzna strona statusu, która co pięć minut sprawdza aplikację i stronę internetową oraz rejestruje incydenty.
Dlaczego
Dostępność jest mierzona spoza infrastruktury, którą opisuje.
- Umami 3.2
-
Samodzielnie hostowana analityka internetowa, która działa dopiero po tym, jak odwiedzający dokona wyboru dotyczącego zgody.
Dlaczego
Dane odwiedzających pozostają w infrastrukturze HansaChat, zamiast zasilać sieć reklamową.
- Remotion 4.0
-
Filmy produktowe są nagrywane w prawdziwej aplikacji przez narzędzie do testów end-to-end i składane w kodzie z lektorem wygenerowanym przez AI.
Dlaczego
Gdy zmienia się interfejs, film jest ponownie renderowany, a nie kręcony od nowa.
- TwentyCRM + WireGuard
-
Samodzielnie hostowany CRM dostępny wyłącznie przez prywatny VPN.
Dlaczego
Dane sprzedażowe w ogóle nie są wystawione do publicznego internetu.
Praktyki inżynierskie
Nawyki, dzięki którym jedna osoba może dostarczać produkt wielodostępny bez osobnego zespołu QA czy utrzymania.
Kontrakty są generowane, nigdy pisane ręcznie
Protobuf jest jedynym źródłem dla serwera w Go, klientów w TypeScript i CLI. Generatory są przypięte do dokładnych wersji, a CLI zapisuje skrót każdego używanego pliku kontraktu.
Migracje prowadzą ewidencję
Każda baza danych przestrzeni roboczej zapisuje, które migracje zastosowała. Hook wdrożeniowy stosuje tylko brakujące i sprawdza ponownie po wdrożeniu. Strona internetowa zachowuje swoje pierwotne migracje bazowe, aby istniejące bazy danych nigdy nie uruchamiały ich dwukrotnie.
Testy end-to-end na odizolowanym środowisku
Jedno polecenie uruchamia bazy danych, NATS, Valkey, Centrifugo i magazyn obiektów na wolnych portach, buduje pliki binarne Go, uruchamia aplikację webową i wykonuje 70 specyfikacji Playwright ze świeżą przestrzenią roboczą dla każdego testu.
Testy na każdej warstwie
478 funkcji testowych w Go, w tym testy izolacji dwóch przestrzeni roboczych, 109 plików Vitest w kliencie i ponad 130 plików Pest w kodzie strony internetowej.
Zabezpieczenia w CI
Kontrole formatowania, limit 1000 wierszy na plik Go i testy chartów Helm działają w CI obok zestawów testów.
Ręczne zatwierdzanie wdrożeń
CI automatycznie buduje i testuje, ale wdrożenia na środowisko przedprodukcyjne i produkcyjne to osobne, ręczne joby. Na produkcję trafia tag wydania, który powstaje dopiero po scaleniu zmiany.
Kopie zapasowe potwierdzone odtworzeniem
Każde wykonanie kopii zapasowej jest monitorowane, a automatyczne ćwiczenie co miesiąc odtwarza bazy danych i weryfikuje tabele oraz liczbę wierszy.
Jeden system projektowy
Strona internetowa i aplikacja korzystają z jednej udokumentowanej palety, skali typograficznej i zasad dotyczących komponentów, z jasnym i ciemnym motywem w aplikacji.
Wspierane przez AI, zatwierdzane przez człowieka
Agenci AI do programowania pracują na podstawie pliku z instrukcjami w każdym repozytorium, który odsyła do jednego centralnego repozytorium dokumentacji inżynierskiej. Powtarzalne procesy, takie jak przebieg testów end-to-end, są spakowane jako umiejętności agentów. Każda zmiana nadal przechodzi te same testy, a wdrożenia pozostają ręczne.
Zarządzanie bezpieczeństwem w przygotowaniu
HansaChat przygotowuje się do certyfikacji ISO/IEC 27001, prowadząc rejestr ryzyk, rejestr dowodów i dziennik decyzji. Obecnie nie posiada certyfikatu.
Co ta strona potwierdza — a czego nie
Wszystko powyżej opisuje to, co jest wdrożone na dziś, i zostało policzone w repozytoriach kodu źródłowego. HansaChat nie twierdzi, że posiada certyfikat bezpieczeństwa. Triaż wiadomości jest w fazie pilotażowej, a powiadomienia push dla zamkniętych aplikacji nie są jeszcze dostępne.
Pytania o architekturę?
Inżynierowie oceniający HansaChat dostają bezpośrednie odpowiedzi od osoby, która go zbudowała.