Hoppa till teknikinnehållet
Tillbaka till startsidan

Teknikstack

HansaChat är en europeisk företagschatt med ett driftlager för fältteam, designad, byggd och driven av en enda person. Den här sidan visar vad varje del är byggd med och varför den valdes.

Versioner och antal granskade i oktober 2026.

Räknat i kodförråden

ConnectRPC-tjänster med 179 RPC-anrop, alla definierade i Protobuf
18
Go-binärer från en kodbas: API, worker, outbox-relä, administration
4
plattformar från en klient: webb, macOS, Windows, Linux, iOS, Android
6
språk på den publika webbplatsen
22
gränssnittsspråk i appen
23
Playwright-specifikationer för end-to-end-tester i en isolerad stack
70

Hur delarna hänger ihop

Tre applikationer delar en edge och ett kluster. Webbplatsen äger faktureringen och arbetsyteregistret, Go-backenden äger allt inom en arbetsyta, och webbappen pratar med backenden via genererade ConnectRPC-klienter.

Klienter

Webbläsare

Webbplats och webbapp

Tauri

Skal för dator och mobil

hansa CLI

Skript och agenter

Edge

Bunny.net CDN

TLS, cachning, DDoS-skydd

IONOS Managed Kubernetes, Tyskland

Traefik

Ingress för varje applikation

Webbapp Vue + Vite

Statiskt Vue-bygge

Chatt-API

Go med ConnectRPC

  • Worker
  • Outbox-relä

Webbplats Laravel + FrankenPHP

Fakturering, register, provisionering

NATS JetStream

Beständiga kommandon och händelser

Centrifugo

WebSocket-distribution

Valkey Sentinel + HAProxy

Cache, närvaro, sessioner

LiveKit

Samtalsmedia

Hanterad data hos IONOS

MariaDB

En databas per arbetsyta plus ett centralt register

Object Storage S3

Filer och avatarer

Externa tjänster

ElevenLabs · LLM · Clef

Transkribering, översättning, triage

Creem · EmailLabs

Betalningar och e-post

Utanför klustret

Cloudflare Workers D1

Externa statuskontroller

Bunny Storage restic

Krypterade säkerhetskopior i Frankfurt och Stockholm

Ett meddelandes väg

  1. Klienten anropar meddelandetjänsten via ConnectRPC.
  2. API-servern accepterar begäran först när NATS JetStream har lagrat kommandot beständigt.
  3. En worker skriver meddelandet och en outbox-händelse till arbetsytans databas i en och samma transaktion.
  4. Outbox-reläet publicerar den committade händelsen till NATS och Centrifugo.
  5. Varje öppen klient tar emot den via WebSocket; efter ett avbrott läser klienterna in det auktoritativa tillståndet från API-servern igen.

Chattbackend

Allt som händer inom en arbetsyta körs i Go: meddelanden, kanaler, filer, samtal, realtid, importer och driftpaketet för städbranschen. Webbplatsen rör aldrig arbetsytedata.

Go 1.26

Fyra binärer från en modulär kodbas: API-servern, meddelande-workern, outbox-reläet och ett skyddat administrationskommando. De levereras som statiska binärer i en enda liten avbild.

Varför

Ett starkt standardbibliotek, förutsägbar prestanda och enkel samtidighet passar en backend som består av långlivade workers. Ett enda språk för hela arbetsytekärnan gör den underhållbar för en person.

ConnectRPC + Protobuf connect-go 1.20 · buf 1.71

18 tjänster och 179 RPC-anrop är definierade i Protobuf. buf genererar Go-servern och TypeScript-klienterna med lokala plugins, så inget schema lämnar maskinen.

Varför

Ett kontrakt betjänar webb-, dator-, mobil- och kommandoradsklienterna. Det finns inga handskrivna HTTP-sökvägar eller manuell svarsparsning, och en kontraktsändring syns som ett kompileringsfel i stället för ett körtidsfel.

En databas per arbetsyta MariaDB · sqlc

Varje arbetsyta får en egen fysisk MariaDB-databas. API-servern slår upp arbetsytan utifrån dess domän och öppnar motsvarande pool; workers slår själva upp den igen och litar aldrig på ett databasnamn från ett kömeddelande. Frågorna är vanlig SQL som sqlc kompilerar till typad Go.

Varför

Isoleringen är strukturell i stället för ett filter i varje fråga. Export, import, återställning och radering fungerar per företag.

NATS JetStream 2.10

Beständiga strömmar för kommandon, jobb och händelser samt en dead-letter-ström. Meddelandeskrivningar körs i 64 ordnade partitioner.

Varför

Ett meddelande accepteras först efter en beständig bekräftelse. Meddelanden i samma kanal behåller sin ordning medan oberoende kanaler bearbetas parallellt.

Transaktionell outbox

Domänrader och den utgående händelsen committas i samma transaktion. Ett relä publicerar committade händelser till NATS och Centrifugo, deduplicerade via händelse-ID, och registrerar fel för nya försök.

Varför

Inga förlorade händelser eller fantomhändelser när en process stoppar mellan databasskrivningen och publiceringen.

Centrifugo v5

WebSocket-leverans av meddelanden, närvaro, skrivindikatorer och samtalsstatus. Klienter prenumererar med kortlivade token per kanal, som API-servern utfärdar först efter att ha kontrollerat medlemskapet i arbetsytan.

Varför

En dedikerad realtidsserver håller långlivade anslutningar borta från API-processen, och varje token anger både arbetsyta och användare, så identiteter från separata databaser kan inte kollidera.

S3-kompatibel objektlagring aws-sdk-go-v2

Filer och avatarer lagras i IONOS Object Storage i EU och lämnas ut via kortlivade signerade länkar.

Varför

Fillagringen skalar oberoende av databaserna och är krypterad i vila på serversidan.

LiveKit 1.9

En egenhostad WebRTC-medieserver för samtal i direktmeddelanden och ljudfokuserade kanalsamtal med kamera och skärmdelning.

Varför

Öppen källkod och möjlig att drifta själv, så samtalsmedia körs på infrastruktur som HansaChat driver.

ElevenLabs Scribe

Tal till text för röstmeddelanden. Transkriptionen kopplas till meddelandet och är sökbar och översättningsbar som all annan text.

Varför

Fältpersonal pratar mer än de skriver.

LLM-översättning

Översättning per läsare via ett OpenAI-kompatibelt API. Varje meddelande översätts vid behov, cachas en gång per målspråk och hoppas över när läsaren redan talar språket.

Varför

Ett flerspråkigt arbetslag arbetar i en och samma konversation medan varje medlem läser på sitt eget språk. Leverantören förblir utbytbar bakom ett enda gränssnitt.

Cloudflare Clef

En beslutsmodell klassificerar operativa meddelanden efter kategori, brådska och konfidens. Den returnerar sannolikheter för fasta frågor, inte genererad text. För närvarande i pilotdrift.

Varför

Det finns ingen fritext att tolka. Arbetsledare ser vad som behöver uppmärksamhet; att agera på det förblir alltid ett mänskligt beslut.

go-pdf 0.9

Tidrapporter och servicerapporter i A4-format genereras på servern.

Varför

Ett rent Go-bibliotek håller backendens avbild liten och fri från en headless-webbläsare.

Sentry + slog

Fel och spår skickas till Sentry, loggar är strukturerad JSON från standardbiblioteket och workers exponerar mätvärden i Prometheus textformat.

Varför

Få rörliga delar att drifta, och varje fel kommer med sitt sammanhang.

Appar och CLI

En Vue-klient betjänar webben och paketeras av Tauri för dator och mobil. Kommandoradsklienten använder samma publika API som apparna.

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

En enda klient med 118 single-file-komponenter, Pinia-stores, vue-router och vue-i18n på 23 gränssnittsspråk, testad med Vitest.

Varför

En mogen, läsbar komponentmodell och strikt TypeScript gör en stor klient hanterbar för ett mycket litet team.

Vite + Tailwind CSS Vite 8 · Tailwind 4

Byggverktyget och stillagret: Tailwind CSS 4 med ett ljust och ett mörkt tema.

Varför

Snabba byggen och designtokens som följer samma dokumenterade palett som webbplatsen.

Tauri 2.10

Paketerar samma webbklient för macOS, Windows, Linux, iOS och Android, med inbyggda aviseringar, djuplänkar och signerade skrivbordsuppdateringar.

Varför

Ett gränssnitt överallt, med systemets webbvy i stället för en webbläsarmotor som buntas med varje app.

Genererade Connect-klienter connect-web 2.1 · protobuf-es 2

TypeScript-klienter som genereras från backendens Protobuf och kopieras in i webbappen. De redigeras aldrig för hand.

Varför

En kontraktsändring blir ett typfel i klienten i stället för en överraskning i produktion.

centrifuge-js + livekit-client 5.7 · 2.20

Klientbiblioteken för Centrifugo-realtid och LiveKit-samtal.

Varför

Återanslutning, återställning och mediehantering kommer från projekten som bygger servrarna.

TipTap 3.22

Meddelandeeditorn, med omnämnanden, länkar och kodblock med syntaxmarkering.

Varför

En strukturerad editor i stället för bräcklig stränghantering.

hansa CLI Go 1.26 · Cobra

En tillståndslös kommandoradsklient för människor, skript och LLM-agenter. JSON-utdata som standard, inloggningsuppgifter i operativsystemets nyckelring och kontrollsummor för releaser signerade med Minisign.

Varför

Den använder samma publika API som apparna. Dess Protobuf-kontrakt kopieras från backenden och låses med SHA-256-hashar, så avvikelser upptäcks i CI.

Webbplats, fakturering och register

Laravel driver den publika webbplatsen, kunddokumentationen, kassan, prenumerationerna och det centrala registret över arbetsytor. Den skapar en arbetsyta genom att anropa Go-backenden över autentiserad HTTP, utan delad kod och utan delade köer.

Laravel + PHP Laravel 12 · PHP 8.5

Den publika webbplatsen, kunddokumentationen, kassan, prenumerationer, rabattkoder, livscykelmeddelanden och det centrala registret över arbetsytor och domäner.

Varför

Fakturering, e-post, schemaläggning, köer och formulär är där Laravel är som starkast. Chatten stannar i Go, och gränsen mellan dem är ett enda autentiserat HTTP-gränssnitt.

FrankenPHP 1.13

PHP-applikationsservern i containeravbilden, byggd på en gemensam basavbild som låser PHP, dess tillägg och verktyg via digest.

Varför

En process betjänar applikationen, och att bygga om samma commit ger samma körmiljö.

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

Serverrenderade sidor med små Alpine.js-komponenter, stylade med Tailwind CSS och buntade av Vite.

Varför

Innehållssidor laddas snabbt utan att leverera ett ramverk för single-page-appar.

22 språk

Varje publik sida finns på 22 EU-språk med språkprefix i URL-adresserna, hreflang-länkar och en lokaliserad webbplatskarta. Ett test misslyckas om något språk saknar en nyckel eller levererar engelsk text.

Varför

En europeisk produkt bör gå att läsa på köparens språk redan från första sidan.

Creem

Kassa, skatt, fakturor och prenumerationer, synkroniserade via signerade webhooks.

Varför

Betalning, skatt och fakturering ligger hos en specialiserad leverantör, medan webbplatsen har en avstämd kopia av varje prenumeration.

EmailLabs

Transaktions- och tjänste-e-post som inbjudningar, lösenordslänkar och meddelanden.

Varför

En e-postleverantör i EU för en EU-produkt.

Pest 4.4

Mer än 130 testfiler täcker rutter, fakturering, provisionering, översättningar och SEO, inklusive webbläsartester.

Varför

Snabba, läsbara tester som körs vid varje ändring.

Plattform och drift

Produktions- och förhandsmiljön körs hos IONOS i Tyskland. Varje applikation levereras som en containeravbild med ett eget Helm-chart och driftsätts av ett manuellt startat GitLab-jobb.

IONOS Managed Kubernetes

Produktions- och förhandskluster, hanterad MariaDB och S3-kompatibel Object Storage, allt drivet av en tysk leverantör i Tyskland.

Varför

En europeisk leverantör under EU-jurisdiktion, inte EU-regionen hos ett icke-europeiskt moln.

Helm + Traefik

Varje applikation levererar sitt eget chart. Traefik dirigerar trafiken inom klustret, och migreringar av arbetsytedatabaser körs som en hook före varje utrullning av backenden.

Varför

Varje driftsättning är versionerad, repeterbar och lätt att rulla tillbaka.

Bunny.net

CDN, DNS och DDoS-skydd framför klustret, samt lagringen för krypterade säkerhetskopior.

Varför

Ett europeiskt företag driver edgen och förvarar säkerhetskopiorna, så ingen av dem är beroende av ett icke-europeiskt moln.

Valkey + Sentinel + HAProxy Valkey 9.1

Tre repliker med Sentinel-failover och en HAProxy-proxy som alltid pekar på den aktuella primärnoden. Den används för cachning, sessioner, närvaro och realtidsbrokern.

Varför

En failover kräver ingen ändring i applikationen, eftersom varje tjänst fortsätter att prata med samma adress.

restic 0.18

Krypterade databassäkerhetskopior med 6 timmars intervall till två platser i EU, med veckovisa integritetskontroller och en automatiserad månatlig återställningsövning.

Varför

En säkerhetskopia räknas först när en återställning har bevisats fungera.

GitLab CI

Tester, avbildsbyggen och kontroller av Helm-charts körs i CI. Driftsättningar till förhandsmiljön och produktion är separata, manuellt startade jobb.

Varför

Automatiseringen sköter det repetitiva arbetet; en människa bestämmer när något når kunderna.

Runt produkten

Verktygen som håller ett enmansföretag observerbart, nåbart och begripligt.

Cloudflare Workers + D1

En extern statussida som kontrollerar appen och webbplatsen var femte minut och registrerar incidenter.

Varför

Tillgängligheten mäts utanför den infrastruktur den beskriver.

Umami 3.2

Egenhostad webbanalys som körs först efter att en besökare har gjort ett samtyckesval.

Varför

Besökardata stannar på HansaChats infrastruktur i stället för att mata ett annonsnätverk.

Remotion 4.0

Produktvideorna spelas in från den riktiga applikationen av end-to-end-testköraren och sätts samman i kod med en AI-genererad speakerröst.

Varför

När gränssnittet ändras renderas videon om i stället för att spelas in på nytt.

TwentyCRM + WireGuard

Ett egenhostat CRM som bara kan nås via ett privat VPN.

Varför

Säljdata exponeras inte mot det publika internet över huvud taget.

Utvecklingspraxis

Vanorna som gör att en enda person kan leverera en multi-tenant-produkt utan separat QA- eller driftteam.

Kontrakt genereras, de skrivs aldrig för hand

Protobuf är den enda källan för Go-servern, TypeScript-klienterna och CLI-klienten. Generatorerna är låsta till exakta versioner, och CLI-klienten registrerar hashen för varje kontraktsfil den använder.

Migreringar för bok

Varje arbetsytedatabas registrerar vilka migreringar den har tillämpat. En hook vid driftsättning tillämpar bara de som saknas och kontrollerar igen efter utrullningen. Webbplatsen behåller sina ursprungliga basmigreringar så att befintliga databaser aldrig kör dem två gånger.

End-to-end-tester i en isolerad stack

Ett kommando startar databaserna, NATS, Valkey, Centrifugo och objektlagring på lediga portar, bygger Go-binärerna, startar webbappen och kör 70 Playwright-specifikationer med en ny arbetsyta för varje test.

Tester i varje lager

478 testfunktioner i Go, inklusive isoleringstester med två arbetsytor, 109 Vitest-filer i klienten och mer än 130 Pest-filer på webbplatsen.

Skyddsräcken i CI

Formateringskontroller, en gräns på 1 000 rader per Go-fil och tester av Helm-charts körs i CI bredvid testsviterna.

Manuella grindar för driftsättning

CI bygger och testar automatiskt, men driftsättningar till förhandsmiljön och produktion är separata manuella jobb. Produktion driftsätter en release-tagg som skapas först efter att ändringen har slagits samman.

Säkerhetskopior bevisade genom återställningar

Varje säkerhetskopiering övervakas, och en automatiserad övning återställer databaserna varje månad och validerar tabeller och radantal.

Ett designsystem

Webbplatsen och appen delar en dokumenterad palett, typografisk skala och komponentregler, med ett ljust och ett mörkt tema i appen.

AI-stöd, mänskligt godkännande

AI-kodagenter arbetar utifrån en instruktionsfil i varje kodförråd som pekar till ett centralt kodförråd för utvecklingsdokumentation. Repeterbara arbetsflöden som end-to-end-körningen är paketerade som agentfärdigheter. Varje ändring måste fortfarande klara samma tester, och driftsättningar förblir manuella.

Säkerhetsledning under förberedelse

HansaChat förbereder sig för certifiering enligt ISO/IEC 27001 med ett riskregister, ett bevisregister och en beslutslogg. HansaChat är inte certifierat i dag.

Vad den här sidan påstår – och vad den inte påstår

Allt ovan beskriver vad som är implementerat i dag och har räknats i källkodsförråden. HansaChat gör inte anspråk på någon säkerhetscertifiering. Meddelandetriage är i pilotdrift, och push-aviseringar för stängda appar är ännu inte i drift.

Frågor om arkitekturen?

Utvecklare som utvärderar HansaChat får direkta svar från personen som byggde det.

Mejla utvecklaren