Przejdź do treści o technologii
Powrót do strony głównej

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

  1. Klient wywołuje usługę wiadomości przez ConnectRPC.
  2. API przyjmuje żądanie dopiero wtedy, gdy NATS JetStream trwale zapisze polecenie.
  3. Worker zapisuje wiadomość i zdarzenie outboxa w bazie danych przestrzeni roboczej w jednej transakcji.
  4. Przekaźnik outboxa publikuje zatwierdzone zdarzenie w NATS i Centrifugo.
  5. 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.

Napisz do twórcy