Backend do Housing Pro
A busca por palavra-chave falha exatamente onde o usuário mais precisa: quando ele descreve o que quer com as palavras dele, e não com as do artigo.
Cada conteúdo é convertido em vetor pelo Ollama e guardado no Postgres com pgvector. A pergunta vira vetor pelo mesmo caminho, e o que volta é o que está mais próximo em significado — não o que repete o termo.
“”
O caminho de uma busca
Embedding é caro e determinístico: gerar de novo o mesmo vetor para o mesmo texto é desperdício. Por isso o conteúdo é vetorizado uma vez, na ingestão, e só a pergunta paga o custo na hora.
Uma vez só, na ingestão. O resultado fica em PostEmbedding, ao lado do texto.
/searchO mesmo modelo do Ollama gera o vetor da pergunta — tem que ser o mesmo, senão os espaços não se comparam.
pgvector faz a comparação dentro do banco. Não há re-ranqueamento em memória na aplicação.
Quem chama decide o corte. A API não esconde o score atrás de um "relevante / não relevante".
Superfície
É um backend pequeno de propósito. O que não é busca semântica nem e-mail transacional mora em outro lugar.
| Rota | Método | Faz |
|---|---|---|
/search | POST | Busca semântica sobre PostEmbedding, por similaridade de vetor. |
/contact | POST | Recebe o lead, grava em Contact e dispara o e-mail pelo Resend. |
/health | GET | Health check. |
Stack
Nada aqui é padrão de mercado por si só — cada peça está aqui resolvendo um problema específico deste backend.
Servidor HTTP mínimo sobre @hono/node-server. Três rotas não justificam um framework com opinião sobre pastas.
O mesmo Postgres guarda os dados e os embeddings. Um banco a menos para operar, e a busca acontece onde os dados já estão.
Embeddings gerados localmente, sem custo por token e sem rate limit — o que importa quando se vetoriza um acervo inteiro de uma vez.
O e-mail transacional é escrito como componente em src/emails, versionado junto com o código que o dispara.
Cache e fila. Evita reprocessar o que já foi respondido e segura picos sem derrubar a ingestão.
O contrato das três rotas é tipado ponta a ponta — inclusive o formato do vetor, que é onde erro silencioso costuma nascer.
Rodar
O único passo fácil de esquecer é a extensão: sem vector habilitada, a migration do
Prisma sobe e a busca falha só na primeira consulta.
# 1 · extensão no banco psql $DATABASE_URL -c "CREATE EXTENSION IF NOT EXISTS vector" # 2 · schema + modelo de embedding npx prisma migrate deploy ollama pull nomic-embed-text # 3 · subir npm run devLer o código no GitHub