Teknologistak
HansaChat er en europæisk virksomhedschat med et driftslag til teams i marken, designet, bygget og drevet af én person. Denne side viser, hvad hver del er bygget med, og hvorfor valget faldt på netop det.
Versioner og antal gennemgået i oktober 2026.
Optalt i repositorierne
- ConnectRPC-tjenester med 179 RPC’er, alle defineret i Protobuf
- 18
- Go-binærfiler fra én kodebase: API, worker, outbox-relay, administration
- 4
- platforme fra én klient: web, macOS, Windows, Linux, iOS, Android
- 6
- sprog på det offentlige websted
- 22
- grænsefladesprog i appen
- 23
- Playwright-end-to-end-specs på en isoleret stak
- 70
Sådan hænger delene sammen
Tre applikationer deler én edge og én klynge. Webstedet ejer fakturering og registret over arbejdsområder, Go-backenden ejer alt inde i et arbejdsområde, og webappen taler med backenden gennem genererede ConnectRPC-klienter.
Klienter
Browser
Websted og webapp
Tauri
Desktop- og mobilskaller
hansa CLI
Scripts og agenter
Edge
Bunny.net CDN
TLS, caching, DDoS-beskyttelse
IONOS Managed Kubernetes, Tyskland
Traefik
Ingress til hver applikation
Webapp Vue + Vite
Statisk Vue-build
Chat-API
Go med ConnectRPC
- Worker
- Outbox-relay
Websted Laravel + FrankenPHP
Fakturering, register, provisionering
NATS JetStream
Holdbare kommandoer og hændelser
Centrifugo
WebSocket-distribution
Valkey Sentinel + HAProxy
Cache, tilstedeværelse, sessioner
LiveKit
Opkaldsmedier
Administrerede data hos IONOS
MariaDB
Én database pr. arbejdsområde plus et centralt register
Object Storage S3
Filer og avatarer
Eksterne tjenester
ElevenLabs · LLM · Clef
Transskription, oversættelse, triage
Creem · EmailLabs
Betalinger og e-mail
Uden for klyngen
Cloudflare Workers D1
Eksterne statustjek
Bunny Storage restic
Krypterede backups i Frankfurt og Stockholm
Vejen for én besked
- Klienten kalder beskedtjenesten via ConnectRPC.
- API’et accepterer først anmodningen, når NATS JetStream har gemt kommandoen holdbart.
- En worker skriver beskeden og en outbox-hændelse til arbejdsområdets database i én transaktion.
- Outbox-relayet publicerer den committede hændelse til NATS og Centrifugo.
- Alle åbne klienter modtager den via WebSocket; efter et afbrud genindlæser klienterne den autoritative tilstand fra API’et.
Chat-backend
Alt, hvad der sker inde i et arbejdsområde, kører i Go: beskeder, kanaler, filer, opkald, realtid, importer og driftspakken til rengøringsbranchen. Webstedet rører aldrig data i arbejdsområderne.
- Go 1.26
-
Fire binærfiler fra én modulær kodebase: API’et, besked-workeren, outbox-relayet og en sikret administrationskommando. De leveres som statiske binærfiler i ét lille image.
Hvorfor
Et stærkt standardbibliotek, forudsigelig ydeevne og enkel samtidighed passer til en backend bestående af langtkørende workers. Ét sprog for hele arbejdsområdekernen gør den vedligeholdelig for én person.
- ConnectRPC + Protobuf connect-go 1.20 · buf 1.71
-
18 tjenester og 179 RPC’er er defineret i Protobuf. buf genererer Go-serveren og TypeScript-klienterne med lokale plugins, så intet skema forlader maskinen.
Hvorfor
Én kontrakt betjener web-, desktop-, mobil- og kommandolinjeklienterne. Der er ingen håndskrevne HTTP-stier eller manuel parsing af svar, og en kontraktændring viser sig som en kompileringsfejl i stedet for en fejl under kørsel.
- Én database pr. arbejdsområde MariaDB · sqlc
-
Hvert arbejdsområde får sin egen fysiske MariaDB-database. API’et finder arbejdsområdet ud fra dets domæne og åbner den tilhørende pool; workers finder det selv igen og stoler aldrig på et databasenavn fra en købesked. Forespørgsler er almindelig SQL, som sqlc kompilerer til typet Go.
Hvorfor
Isolationen er strukturel i stedet for et filter på hver forespørgsel. Eksport, import, gendannelse og sletning fungerer pr. virksomhed.
- NATS JetStream 2.10
-
Holdbare streams til kommandoer, jobs og hændelser samt en dead-letter-stream. Skrivninger af beskeder kører i 64 ordnede partitioner.
Hvorfor
En besked accepteres først efter en holdbar bekræftelse. Beskeder i samme kanal bevarer deres rækkefølge, mens uafhængige kanaler behandles parallelt.
- Transaktionel outbox
-
Domænerækker og den udgående hændelse committes i samme transaktion. Et relay publicerer committede hændelser til NATS og Centrifugo, deduplikeret efter hændelses-id, og registrerer fejl til et nyt forsøg.
Hvorfor
Ingen tabte hændelser eller fantomhændelser, når en proces stopper mellem databaseskrivningen og publiceringen.
- Centrifugo v5
-
WebSocket-levering af beskeder, tilstedeværelse, skriveindikatorer og opkaldsstatus. Klienter abonnerer med kortlivede tokens pr. kanal, som API’et først udsteder efter at have kontrolleret medlemskabet af arbejdsområdet.
Hvorfor
En dedikeret realtidsserver holder langlivede forbindelser ude af API-processen, og hvert token angiver både arbejdsområde og bruger, så identiteter fra separate databaser ikke kan kollidere.
- S3-kompatibel objektlagring aws-sdk-go-v2
-
Filer og avatarer gemmes i IONOS Object Storage i EU og udleveres via kortlivede signerede links.
Hvorfor
Fillagringen skalerer uafhængigt af databaserne og er krypteret i hvile på serversiden.
- LiveKit 1.9
-
En selvhostet WebRTC-medieserver til opkald i direkte beskeder og lydbaserede kanalopkald med kamera og skærmdeling.
Hvorfor
Open source og selvhostbar, så opkaldsmedier kører på infrastruktur, som HansaChat selv driver.
- ElevenLabs Scribe
-
Tale til tekst for talebeskeder. Transskriptionen knyttes til beskeden og kan søges i og oversættes som al anden tekst.
Hvorfor
Medarbejdere i marken taler mere, end de skriver.
- LLM-oversættelse
-
Oversættelse pr. læser via et OpenAI-kompatibelt API. Hver besked oversættes efter behov, caches én gang pr. målsprog og springes over, når læseren allerede taler sproget.
Hvorfor
Et flersproget hold arbejder i én samtale, mens hvert medlem læser på sit eget sprog. Udbyderen kan fortsat udskiftes bag én grænseflade.
- Cloudflare Clef
-
En beslutningsmodel klassificerer driftsbeskeder efter kategori, hastegrad og konfidens. Den returnerer sandsynligheder for faste spørgsmål, ikke genereret tekst. I øjeblikket i pilotdrift.
Hvorfor
Der er intet fritekstoutput at parse. Arbejdsledere ser, hvad der kræver opmærksomhed; at handle på det forbliver altid en menneskelig beslutning.
- go-pdf 0.9
-
A4-timesedler og servicerapporter genereres på serveren.
Hvorfor
Et rent Go-bibliotek holder backend-imaget lille og fri for en headless browser.
- Sentry + slog
-
Fejl og traces sendes til Sentry, logs er struktureret JSON fra standardbiblioteket, og workers eksponerer metrikker i Prometheus-tekstformatet.
Hvorfor
Få bevægelige dele at drive, og hver fejl ankommer med sin kontekst.
Apps og CLI
Én Vue-klient betjener webben og pakkes af Tauri til desktop og mobil. Kommandolinjeklienten bruger det samme offentlige API som apperne.
- Vue 3 + TypeScript Vue 3.5 · TS 5.9 · Pinia 3
-
Én klient med 118 single-file-komponenter, Pinia-stores, vue-router og vue-i18n på 23 grænsefladesprog, testet med Vitest.
Hvorfor
En moden, læsbar komponentmodel og streng TypeScript gør en stor klient håndterbar for et meget lille team.
- Vite + Tailwind CSS Vite 8 · Tailwind 4
-
Byggeværktøjet og stylinglaget: Tailwind CSS 4 med et lyst og et mørkt tema.
Hvorfor
Hurtige builds og designtokens, der følger samme dokumenterede palet som webstedet.
- Tauri 2.10
-
Pakker den samme webklient til macOS, Windows, Linux, iOS og Android med native notifikationer, deep links og signerede desktopopdateringer.
Hvorfor
Én grænseflade overalt, der bruger systemets webview i stedet for at bundte en browsermotor i hver app.
- Genererede Connect-klienter connect-web 2.1 · protobuf-es 2
-
TypeScript-klienter, der genereres fra backendens Protobuf og kopieres ind i webappen. De redigeres aldrig i hånden.
Hvorfor
En kontraktændring bliver til en typefejl i klienten i stedet for en overraskelse i produktion.
- centrifuge-js + livekit-client 5.7 · 2.20
-
Klientbibliotekerne til Centrifugo-realtid og LiveKit-opkald.
Hvorfor
Genforbindelse, gendannelse og mediehåndtering kommer fra de projekter, der bygger serverne.
- TipTap 3.22
-
Beskededitoren med omtaler, links og kodeblokke med syntaksfremhævning.
Hvorfor
En struktureret editor i stedet for skrøbelig strenghåndtering.
- hansa CLI Go 1.26 · Cobra
-
En tilstandsløs kommandolinjeklient til mennesker, scripts og LLM-agenter. JSON-output som standard, legitimationsoplysninger i operativsystemets nøglering og release-checksummer signeret med Minisign.
Hvorfor
Den bruger det samme offentlige API som apperne. Dens Protobuf-kontrakter kopieres fra backenden og låses med SHA-256-hashes, så afvigelser opdages i CI.
Websted, fakturering og register
Laravel driver det offentlige websted, kundedokumentationen, checkout, abonnementer og det centrale register over arbejdsområder. Det opretter et arbejdsområde ved at kalde Go-backenden over godkendt HTTP, uden delt kode og uden delte køer.
- Laravel + PHP Laravel 12 · PHP 8.5
-
Det offentlige websted, kundedokumentationen, checkout, abonnementer, rabatkoder, livscyklusmeddelelser og det centrale register over arbejdsområder og domæner.
Hvorfor
Fakturering, e-mail, planlægning, køer og formularer er Laravels stærkeste sider. Chatten bliver i Go, og grænsen mellem dem er én godkendt HTTP-grænseflade.
- FrankenPHP 1.13
-
PHP-applikationsserveren i container-imaget, bygget på et fælles base-image, der fastlåser PHP, dets udvidelser og værktøjer via digest.
Hvorfor
Én proces betjener applikationen, og et nyt build af samme commit giver det samme runtime-miljø.
- Blade + Alpine.js + Tailwind CSS Alpine 3.15 · Tailwind 3.4 · Vite 7
-
Serverrenderede sider med små Alpine.js-komponenter, stylet med Tailwind CSS og bundtet af Vite.
Hvorfor
Indholdssider indlæses hurtigt uden at levere et single-page-app-framework.
- 22 sprog
-
Hver offentlig side findes på 22 EU-sprog med sprogpræfiks i URL’erne, hreflang-links og et lokaliseret sitemap. En test fejler, hvis et sprog mangler en nøgle eller leverer engelsk tekst.
Hvorfor
Et europæisk produkt bør kunne læses på købers eget sprog fra første side.
- Creem
-
Checkout, moms, fakturaer og abonnementer, holdt synkroniseret via signerede webhooks.
Hvorfor
Betaling, moms og fakturering ligger hos en specialiseret udbyder, mens webstedet fører en afstemt kopi af hvert abonnement.
- EmailLabs
-
Transaktions- og service-e-mails som invitationer, adgangskodelinks og meddelelser.
Hvorfor
En EU-e-mailudbyder til et EU-produkt.
- Pest 4.4
-
Mere end 130 testfiler dækker ruter, fakturering, provisionering, oversættelser og SEO, inklusive browsertests.
Hvorfor
Hurtige, læsbare tests, der kører ved hver ændring.
Platform og drift
Produktion og preview kører hos IONOS i Tyskland. Hver applikation leveres som et container-image med sit eget Helm-chart og udrulles af et manuelt udløst GitLab-job.
- IONOS Managed Kubernetes
-
Produktions- og preview-klynger, administreret MariaDB og S3-kompatibel Object Storage, alt sammen drevet af en tysk udbyder i Tyskland.
Hvorfor
En europæisk udbyder under EU-jurisdiktion, ikke EU-regionen hos en ikke-europæisk cloud.
- Helm + Traefik
-
Hver applikation leverer sit eget chart. Traefik router trafikken inde i klyngen, og migreringer af arbejdsområdedatabaser kører som en hook før hver udrulning af backenden.
Hvorfor
Hver udrulning er versioneret, gentagelig og nem at rulle tilbage.
- Bunny.net
-
CDN, DNS og DDoS-beskyttelse foran klyngen samt lageret til krypterede backups.
Hvorfor
En europæisk virksomhed driver edgen og opbevarer backup-kopierne, så ingen af dem afhænger af en ikke-europæisk cloud.
- Valkey + Sentinel + HAProxy Valkey 9.1
-
Tre replikaer med Sentinel-failover og en HAProxy-proxy, der altid peger på den aktuelle primære node. Den understøtter caching, sessioner, tilstedeværelse og realtidsbrokeren.
Hvorfor
En failover kræver ingen ændring i applikationen, fordi hver tjeneste bliver ved med at tale med den samme adresse.
- restic 0.18
-
Krypterede databasebackups hver 6. time til to placeringer i EU med ugentlige integritetstjek og en automatiseret månedlig gendannelsesøvelse.
Hvorfor
En backup tæller først, når en gendannelse er bevist.
- GitLab CI
-
Tests, image-builds og tjek af Helm-charts kører i CI. Udrulninger til preview og produktion er separate, manuelt udløste jobs.
Hvorfor
Automatiseringen klarer det gentagne arbejde; et menneske beslutter, hvornår noget når kunderne.
Omkring produktet
De værktøjer, der holder en enkeltmandsvirksomhed observerbar, tilgængelig og forklarlig.
- Cloudflare Workers + D1
-
En ekstern statusside, der tjekker appen og webstedet hvert femte minut og registrerer hændelser.
Hvorfor
Tilgængelighed måles uden for den infrastruktur, den beskriver.
- Umami 3.2
-
Selvhostet webanalyse, der først kører, når en besøgende har truffet et samtykkevalg.
Hvorfor
Besøgsdata forbliver på HansaChats infrastruktur i stedet for at fodre et annoncenetværk.
- Remotion 4.0
-
Produktvideoerne optages fra den rigtige applikation af end-to-end-testkøreren og sammensættes i kode med en AI-genereret speak.
Hvorfor
Når grænsefladen ændres, renderes videoen igen i stedet for at blive filmet forfra.
- TwentyCRM + WireGuard
-
Et selvhostet CRM, der kun kan nås via et privat VPN.
Hvorfor
Salgsdata er slet ikke eksponeret mod det offentlige internet.
Udviklingspraksis
De vaner, der gør det muligt for én person at levere et multi-tenant-produkt uden et separat QA- eller driftsteam.
Kontrakter genereres og skrives aldrig i hånden
Protobuf er den eneste kilde for Go-serveren, TypeScript-klienterne og CLI’en. Generatorerne er fastlåst til præcise versioner, og CLI’en registrerer hashen af hver kontraktfil, den bruger.
Migreringer fører regnskab
Hver arbejdsområdedatabase registrerer, hvilke migreringer den har anvendt. En udrulningshook anvender kun de manglende og tjekker igen efter udrulningen. Webstedet beholder sine oprindelige baseline-migreringer, så eksisterende databaser aldrig kører dem to gange.
End-to-end-tests på en isoleret stak
Én kommando starter databaserne, NATS, Valkey, Centrifugo og objektlagring på ledige porte, bygger Go-binærfilerne, starter webappen og kører 70 Playwright-specs med et nyt arbejdsområde til hver test.
Tests på hvert lag
478 Go-testfunktioner, herunder isolationstests med to arbejdsområder, 109 Vitest-filer i klienten og mere end 130 Pest-filer på webstedet.
Værn i CI
Formateringstjek, en grænse på 1.000 linjer pr. Go-fil og tests af Helm-charts kører i CI ved siden af testsuiterne.
Manuel godkendelse før udrulning
CI bygger og tester automatisk, men udrulninger til preview og produktion er separate manuelle jobs. Produktion udruller et release-tag, der først oprettes, efter at ændringen er merget.
Backups bevist ved gendannelser
Hver backupkørsel overvåges, og en automatiseret øvelse gendanner databaserne hver måned og validerer tabeller og rækkeantal.
Ét designsystem
Webstedet og appen deler én dokumenteret palet, typeskala og komponentregler med et lyst og et mørkt tema i appen.
AI-assisteret, godkendt af mennesker
AI-kodeagenter arbejder ud fra en instruktionsfil i hvert repository, der peger på ét centralt repository med udviklingsdokumentation. Gentagelige arbejdsgange som end-to-end-kørslen er pakket som agent-skills. Hver ændring skal stadig bestå de samme tests, og udrulninger forbliver manuelle.
Sikkerhedsstyring under forberedelse
HansaChat forbereder sig på ISO/IEC 27001-certificering med et risikoregister, et evidensregister og en beslutningslog. HansaChat er ikke certificeret i dag.
Hvad denne side påstår – og hvad den ikke påstår
Alt ovenfor beskriver, hvad der er implementeret i dag, og er optalt i kilderepositorierne. HansaChat gør ikke krav på en sikkerhedscertificering. Beskedtriage er i pilotdrift, og push-notifikationer for lukkede apps er endnu ikke live.
Spørgsmål om arkitekturen?
Udviklere, der evaluerer HansaChat, får direkte svar fra den person, der har bygget det.