Ir para o conteúdo sobre tecnologia
Voltar à página inicial

Stack tecnológica

A HansaChat é um chat empresarial europeu com uma camada operacional para equipas no terreno, concebido, desenvolvido e operado por uma única pessoa. Esta página mostra com que tecnologia é construída cada parte e porque foi escolhida.

Versões e contagens revistas em outubro de 2026.

Contado nos repositórios

serviços ConnectRPC com 179 RPC, todos definidos em Protobuf
18
binários Go a partir de uma única base de código: API, worker, retransmissor de outbox, administração
4
plataformas a partir de um único cliente: web, macOS, Windows, Linux, iOS, Android
6
idiomas no website público
22
idiomas de interface na aplicação
23
especificações end-to-end com Playwright num ambiente isolado
70

Como as peças encaixam

Três aplicações partilham uma mesma camada edge e um mesmo cluster. O website é responsável pela faturação e pelo registo de espaços de trabalho, o backend em Go por tudo o que acontece dentro de um espaço de trabalho, e a aplicação web comunica com o backend através de clientes ConnectRPC gerados.

Clientes

Navegador

Website e aplicação web

Tauri

Invólucros para computador e dispositivos móveis

hansa CLI

Scripts e agentes

Edge

Bunny.net CDN

TLS, cache, proteção DDoS

IONOS Managed Kubernetes, Alemanha

Traefik

Ingress para cada aplicação

Aplicação web Vue + Vite

Build estática de Vue

API do chat

Go com ConnectRPC

  • Worker
  • Retransmissor de outbox

Website Laravel + FrankenPHP

Faturação, registo, aprovisionamento

NATS JetStream

Comandos e eventos duráveis

Centrifugo

Difusão por WebSocket

Valkey Sentinel + HAProxy

Cache, presença, sessões

LiveKit

Multimédia das chamadas

Dados geridos na IONOS

MariaDB

Uma base de dados por espaço de trabalho, mais um registo central

Armazenamento de objetos S3

Ficheiros e avatares

Serviços externos

ElevenLabs · LLM · Clef

Transcrição, tradução, triagem

Creem · EmailLabs

Pagamentos e e-mail

Fora do cluster

Cloudflare Workers D1

Verificações de estado externas

Bunny Storage restic

Cópias de segurança encriptadas em Frankfurt e Estocolmo

O percurso de uma mensagem

  1. O cliente chama o serviço de mensagens através de ConnectRPC.
  2. A API só aceita o pedido depois de o NATS JetStream ter armazenado o comando de forma durável.
  3. Um worker escreve a mensagem e um evento de outbox na base de dados do espaço de trabalho numa única transação.
  4. O retransmissor de outbox publica o evento confirmado no NATS e no Centrifugo.
  5. Todos os clientes abertos o recebem por WebSocket; após uma interrupção, os clientes voltam a carregar o estado de referência a partir da API.

Backend do chat

Tudo o que acontece dentro de um espaço de trabalho é executado em Go: mensagens, canais, ficheiros, chamadas, tempo real, importações e o pacote operacional para empresas de limpeza. O website nunca toca nos dados dos espaços de trabalho.

Go 1.26

Quatro binários a partir de uma base de código modular: a API, o worker de mensagens, o retransmissor de outbox e um comando de administração protegido. São distribuídos como binários estáticos numa única imagem pequena.

Porquê

Uma biblioteca padrão sólida, um desempenho previsível e uma concorrência simples adequam-se a um backend composto por workers de longa duração. Uma única linguagem para todo o núcleo do espaço de trabalho permite que uma só pessoa o mantenha.

ConnectRPC + Protobuf connect-go 1.20 · buf 1.71

18 serviços e 179 RPC estão definidos em Protobuf. O buf gera o servidor Go e os clientes TypeScript com plugins locais, pelo que nenhum esquema sai da máquina.

Porquê

Um único contrato serve os clientes web, de computador, móveis e de linha de comandos. Não há caminhos HTTP escritos à mão nem análise manual de respostas, e uma alteração ao contrato surge como erro de compilação em vez de uma falha em tempo de execução.

Uma base de dados por espaço de trabalho MariaDB · sqlc

Cada espaço de trabalho tem a sua própria base de dados MariaDB física. A API identifica o espaço de trabalho pelo seu domínio e abre o pool correspondente; os workers voltam a identificá-lo por si próprios e nunca confiam num nome de base de dados recebido numa mensagem de fila. As consultas são SQL simples compilado para Go tipado com o sqlc.

Porquê

O isolamento é estrutural, e não um filtro em cada consulta. A exportação, a importação, a reposição e a eliminação funcionam por empresa.

NATS JetStream 2.10

Streams duráveis para comandos, tarefas e eventos, além de um stream de mensagens não entregues (dead-letter). As escritas de mensagens são executadas em 64 partições ordenadas.

Porquê

Uma mensagem só é aceite após uma confirmação durável. As mensagens de um mesmo canal mantêm a ordem, enquanto canais independentes são processados em paralelo.

Outbox transacional

As linhas de domínio e o evento de saída são confirmados na mesma transação. Um retransmissor publica os eventos confirmados no NATS e no Centrifugo, sem duplicados graças ao ID do evento, e regista as falhas para nova tentativa.

Porquê

Nenhum evento perdido ou fantasma quando um processo para entre a escrita na base de dados e a publicação.

Centrifugo v5

Entrega por WebSocket de mensagens, presença, indicadores de escrita e estado das chamadas. Os clientes subscrevem com tokens de curta duração por canal, que a API só emite depois de verificar a pertença ao espaço de trabalho.

Porquê

Um servidor de tempo real dedicado mantém as ligações de longa duração fora do processo da API, e cada token identifica tanto o espaço de trabalho como o utilizador, pelo que identidades de bases de dados diferentes não podem colidir.

Armazenamento de objetos compatível com S3 aws-sdk-go-v2

Os ficheiros e avatares são armazenados no IONOS Object Storage na UE e disponibilizados através de ligações assinadas de curta duração.

Porquê

O armazenamento de ficheiros escala de forma independente das bases de dados e é encriptado em repouso no lado do servidor.

LiveKit 1.9

Um servidor multimédia WebRTC auto-alojado para chamadas em mensagens diretas e chamadas de canal centradas no áudio, com câmara e partilha de ecrã.

Porquê

É de código aberto e pode ser auto-alojado, pelo que a multimédia das chamadas circula em infraestrutura operada pela HansaChat.

ElevenLabs Scribe

Conversão de voz em texto para mensagens de voz. A transcrição fica anexada à mensagem, pesquisável e traduzível como qualquer texto.

Porquê

As equipas no terreno falam mais do que escrevem.

Tradução com LLM

Tradução por leitor através de uma API compatível com OpenAI. Cada mensagem é traduzida a pedido, guardada em cache uma vez por idioma de destino e ignorada quando o leitor já partilha o idioma.

Porquê

Uma equipa multilingue trabalha numa única conversa, enquanto cada membro lê no seu próprio idioma. O fornecedor continua substituível por trás de uma única interface.

Cloudflare Clef

Um modelo de decisão classifica as mensagens operacionais por categoria, urgência e grau de confiança. Devolve probabilidades para perguntas fixas, não texto gerado. Atualmente em fase piloto.

Porquê

Não há saída de texto livre para interpretar. Os supervisores veem o que exige atenção; agir sobre isso continua a ser sempre uma decisão humana.

go-pdf 0.9

As folhas de horas e os relatórios de serviço em formato A4 são gerados no servidor.

Porquê

Uma biblioteca escrita inteiramente em Go mantém a imagem do backend pequena e sem um navegador headless.

Sentry + slog

Os erros e os traces vão para o Sentry, os logs são JSON estruturado gerado pela biblioteca padrão e os workers expõem métricas no formato de texto do Prometheus.

Porquê

Poucas peças móveis para operar, e cada falha chega com o respetivo contexto.

Aplicações e CLI

Um único cliente Vue serve a versão web e é empacotado pelo Tauri para computador e dispositivos móveis. O cliente de linha de comandos utiliza a mesma API pública que as aplicações.

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

Um único cliente com 118 componentes de ficheiro único, stores Pinia, vue-router e vue-i18n em 23 idiomas de interface, testado com Vitest.

Porquê

Um modelo de componentes maduro e legível e um TypeScript rigoroso tornam um cliente grande gerível para uma equipa muito pequena.

Vite + Tailwind CSS Vite 8 · Tailwind 4

A ferramenta de build e a camada de estilos: Tailwind CSS 4 com um tema claro e um tema escuro.

Porquê

Builds rápidas e design tokens que seguem a mesma paleta documentada que o website.

Tauri 2.10

Empacota o mesmo cliente web para macOS, Windows, Linux, iOS e Android, com notificações nativas, deep links e atualizações assinadas para computador.

Porquê

Uma única interface em todo o lado, usando a webview do sistema em vez de incluir um motor de navegador em cada aplicação.

Clientes Connect gerados connect-web 2.1 · protobuf-es 2

Clientes TypeScript gerados a partir do Protobuf do backend e copiados para a aplicação web. Nunca são editados à mão.

Porquê

Uma alteração ao contrato torna-se um erro de tipo no cliente em vez de uma surpresa em produção.

centrifuge-js + livekit-client 5.7 · 2.20

As bibliotecas cliente para o tempo real do Centrifugo e as chamadas LiveKit.

Porquê

A religação, a recuperação e o tratamento de multimédia vêm dos mesmos projetos que desenvolvem os servidores.

TipTap 3.22

O editor de mensagens, com menções, ligações e blocos de código com realce de sintaxe.

Porquê

Um editor estruturado em vez de uma manipulação frágil de cadeias de caracteres.

hansa CLI Go 1.26 · Cobra

Um cliente de linha de comandos sem estado para pessoas, scripts e agentes LLM. Saída JSON por predefinição, credenciais no porta-chaves do sistema operativo e somas de verificação das versões assinadas com Minisign.

Porquê

Utiliza a mesma API pública que as aplicações. Os seus contratos Protobuf são copiados do backend e fixados com hashes SHA-256, pelo que qualquer divergência é detetada na CI.

Website, faturação e registo

O Laravel gere o site público, a documentação para clientes, o checkout, as subscrições e o registo central de espaços de trabalho. Cria um espaço de trabalho chamando o backend em Go por HTTP autenticado, sem código partilhado nem filas partilhadas.

Laravel + PHP Laravel 12 · PHP 8.5

O website público, a documentação para clientes, o checkout, as subscrições, os cupões, os avisos do ciclo de vida e o registo central de espaços de trabalho e domínios.

Porquê

Faturação, e-mail, agendamento, filas e formulários são os pontos fortes do Laravel. O chat fica em Go, e a fronteira entre ambos é uma única interface HTTP autenticada.

FrankenPHP 1.13

O servidor de aplicações PHP dentro da imagem de contentor, construído sobre uma imagem base partilhada que fixa o PHP, as suas extensões e ferramentas por digest.

Porquê

Um único processo serve a aplicação, e reconstruir o mesmo commit produz o mesmo ambiente de execução.

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

Páginas renderizadas no servidor com pequenos componentes Alpine.js, estilizadas com Tailwind CSS e empacotadas pelo Vite.

Porquê

As páginas de conteúdo carregam depressa sem enviar uma framework de aplicação de página única.

22 idiomas

Cada página pública existe em 22 idiomas da UE, com URL prefixados pelo idioma, ligações hreflang e um sitemap localizado. Um teste falha se faltar uma chave a algum idioma ou se este apresentar texto em inglês.

Porquê

Um produto europeu deve poder ser lido no idioma do comprador desde a primeira página.

Creem

Checkout, impostos, faturas e subscrições, mantidos sincronizados através de webhooks assinados.

Porquê

Pagamentos, impostos e faturação ficam a cargo de um fornecedor especializado, enquanto o website mantém uma cópia reconciliada de cada subscrição.

EmailLabs

E-mail transacional e de serviço, como convites, ligações de palavra-passe e avisos.

Porquê

Um fornecedor de e-mail da UE para um produto da UE.

Pest 4.4

Mais de 130 ficheiros de testes cobrem rotas, faturação, aprovisionamento, traduções e SEO, incluindo testes no navegador.

Porquê

Testes rápidos e legíveis, executados a cada alteração.

Plataforma e operações

A produção e a pré-produção são executadas na IONOS, na Alemanha. Cada aplicação é entregue como imagem de contentor com o seu próprio chart Helm e implementada por um job do GitLab acionado manualmente.

IONOS Managed Kubernetes

Clusters de produção e de pré-produção, MariaDB gerido e Object Storage compatível com S3, tudo operado por um fornecedor alemão na Alemanha.

Porquê

Um fornecedor europeu sob jurisdição da UE, e não a região europeia de uma cloud não europeia.

Helm + Traefik

Cada aplicação tem o seu próprio chart. O Traefik encaminha o tráfego dentro do cluster, e as migrações das bases de dados dos espaços de trabalho são executadas como hook antes de cada implementação do backend.

Porquê

Cada implementação é versionada, repetível e fácil de reverter.

Bunny.net

CDN, DNS e proteção DDoS à frente do cluster, além do armazenamento para as cópias de segurança encriptadas.

Porquê

Uma empresa europeia opera a camada edge e guarda as cópias de segurança, pelo que nenhuma delas depende de uma cloud não europeia.

Valkey + Sentinel + HAProxy Valkey 9.1

Três réplicas com failover através do Sentinel e um proxy HAProxy que aponta sempre para o primário atual. Suporta a cache, as sessões, a presença e o broker de tempo real.

Porquê

Um failover não exige alterações na aplicação, porque todos os serviços continuam a comunicar com o mesmo endereço.

restic 0.18

Cópias de segurança encriptadas das bases de dados a cada 6 horas para duas localizações na UE, com verificações de integridade semanais e um exercício de reposição mensal automatizado.

Porquê

Uma cópia de segurança só conta depois de uma reposição o comprovar.

GitLab CI

Os testes, a build das imagens e as verificações dos charts Helm são executados na CI. As implementações em pré-produção e em produção são jobs separados, acionados manualmente.

Porquê

A automação faz o trabalho repetitivo; uma pessoa decide quando algo chega aos clientes.

À volta do produto

As ferramentas que mantêm uma empresa de uma só pessoa observável, contactável e explicável.

Cloudflare Workers + D1

Uma página de estado externa que verifica a aplicação e o website a cada cinco minutos e regista os incidentes.

Porquê

A disponibilidade é medida a partir de fora da infraestrutura que descreve.

Umami 3.2

Análise web auto-alojada que só é executada depois de o visitante ter feito uma escolha de consentimento.

Porquê

Os dados dos visitantes permanecem na infraestrutura da HansaChat em vez de alimentarem uma rede de publicidade.

Remotion 4.0

Os vídeos do produto são gravados a partir da aplicação real pelo executor de testes end-to-end e compostos em código com uma locução gerada por IA.

Porquê

Quando a interface muda, o vídeo é novamente renderizado em vez de ser filmado outra vez.

TwentyCRM + WireGuard

Um CRM auto-alojado acessível apenas através de uma VPN privada.

Porquê

Os dados comerciais não estão de todo expostos à internet pública.

Práticas de engenharia

Os hábitos que permitem a uma só pessoa entregar um produto multi-inquilino sem uma equipa separada de QA ou de operações.

Os contratos são gerados, nunca escritos à mão

O Protobuf é a fonte única para o servidor Go, os clientes TypeScript e a CLI. Os geradores estão fixados em versões exatas, e a CLI regista o hash de cada ficheiro de contrato que utiliza.

As migrações mantêm um registo

Cada base de dados de espaço de trabalho regista as migrações que já aplicou. Um hook de implementação aplica apenas as que faltam e volta a verificar após a implementação. O website mantém as suas migrações de base originais, para que as bases de dados existentes nunca as executem duas vezes.

Testes end-to-end num ambiente isolado

Um único comando arranca as bases de dados, o NATS, o Valkey, o Centrifugo e o armazenamento de objetos em portas livres, compila os binários Go, inicia a aplicação web e executa 70 especificações Playwright com um espaço de trabalho novo para cada teste.

Testes em todas as camadas

478 funções de teste em Go, incluindo testes de isolamento entre dois espaços de trabalho, 109 ficheiros Vitest no cliente e mais de 130 ficheiros Pest no website.

Salvaguardas na CI

Verificações de formatação, um limite de 1000 linhas por ficheiro Go e testes dos charts Helm são executados na CI, ao lado dos conjuntos de testes.

Aprovação manual das implementações

A CI compila e testa automaticamente, mas as implementações em pré-produção e em produção são jobs manuais separados. A produção implementa uma tag de versão que só é criada depois de a alteração ser integrada (merge).

Cópias de segurança comprovadas por reposições

Cada execução de cópia de segurança é monitorizada, e um exercício automatizado repõe as bases de dados todos os meses e valida as tabelas e o número de linhas.

Um único sistema de design

O website e a aplicação partilham uma paleta documentada, uma escala tipográfica e regras de componentes, com um tema claro e um tema escuro na aplicação.

Assistido por IA, aprovado por pessoas

Os agentes de programação com IA trabalham a partir de um ficheiro de instruções em cada repositório, que remete para um repositório central de documentação de engenharia. Fluxos de trabalho repetíveis, como a execução end-to-end, estão empacotados como skills de agente. Cada alteração continua a passar pelos mesmos testes, e as implementações continuam manuais.

Gestão da segurança em preparação

A HansaChat está a preparar-se para a certificação ISO/IEC 27001, com um registo de riscos, um registo de evidências e um registo de decisões. Atualmente não está certificada.

O que esta página afirma — e o que não afirma

Tudo o que foi descrito acima está implementado hoje e foi contado a partir dos repositórios de código-fonte. A HansaChat não alega qualquer certificação de segurança. A triagem de mensagens está em fase piloto, e as notificações push para aplicações fechadas ainda não estão disponíveis.

Dúvidas sobre a arquitetura?

Os engenheiros que avaliam a HansaChat recebem respostas diretas da pessoa que a construiu.

Enviar e-mail ao programador