Saltar para o conteúdo
megapromotingVamos falar

Especialização · Manutenção

Manutenção significa saber que o formulário entrega hoje, não que o servidor responde 200.

Monitorização que verifica o percurso completo de um pedido até uma pessoa, atualizações com gate antes da produção e uma verificação de aceitação executada após cada publicação. As três correm neste site e podem ser abertas a partir do exterior.

Já construídoTrês implementações próprias, todas no repositório deste site e todas verificáveis hoje: `src/app/api/health/contact/route.ts` (a sonda de entrega, responde 200 em live neste momento), `src/lib/lead-store.ts` (o registo append-only com retenção aplicada na escrita) e `scripts/verify-redesign.ts` (a verificação de aceitação executada após a publicação). Escrevemo-las porque em 06.09.2026 o formulário próprio caiu em silêncio: o token do bot tinha sido revogado, o endpoint devolvia 500 e os pedidos desapareciam sem deixar rasto. Não é uma história de venda — é o commit que produziu os ficheiros acima.

“O site funciona” é uma afirmação sobre a página inicial. Um visitante que preencheu o formulário e recebeu um erro não foi bloqueado por uma página em baixo, mas por um canal de entrega que expirou em silêncio. A diferença entre as duas coisas é tudo o que significa manutenção feita a sério: não seguimos se o servidor responde, mas se um pedido de uma pessoa chega a outra pessoa.

Em 6 de setembro de 2026 aconteceu exatamente isso neste site. O token do bot que encaminhava os pedidos do formulário para a equipa foi revogado; a interface do Telegram respondia `401 Unauthorized`, a nossa rota devolvia 500 e o visitante via “a mensagem não pôde ser enviada”. O pedido não era escrito em lado nenhum. No registo de erros do processo havia três falhas reais nas cerca de sete horas decorridas desde a publicação anterior. Ninguém estava a ver.

O que saiu disto são três peças que agora montamos em cada projeto que mantemos. Um registo append-only escrito *antes* da tentativa de entrega, para que um canal estragado degrade para “temos de olhar para o ficheiro” em vez de “o pedido nunca existiu”. Uma sonda de saúde que responde a um único pedido se um lead pode chegar a uma pessoa agora. E uma verificação de aceitação que corre após cada publicação e falha se tiver desaparecido um endereço canónico, uma âncora de perguntas ou se no sitemap tiverem aparecido endereços que não se podem abrir.

O resto é disciplina aborrecida e verificável: atualizações com um gate de auditoria antes de tocar em produção, reinício automático com limiar de memória e limite de reinícios instáveis, retenção aplicada por código, não declarada na política, e endereços IP truncados ao prefixo de rede antes de serem escritos em qualquer lado.

Qué incluye

El trabajo, por componentes

Sonda que verifica a entrega, não a disponibilidade

`GET /api/health/contact` responde 200 se um lead puder chegar a uma pessoa agora e 503 se não. Verifica duas coisas separadamente: que o token do canal de notificação ainda é válido (um pedido real ao fornecedor, com timeout de 8 segundos) e que o registo de pedidos é gravável. A resposta é composta apenas por valores lógicos — nunca o token, o identificador do canal ou o nome do bot. O resultado é mantido em memória durante 60 segundos, para que uma sonda externa pressionada com frequência não se torne ela própria tráfego. Quando o fornecedor está inacessível, o campo torna-se `null`, não `false`: “não sei” e “inválido” são estados diferentes.

Registo escrito antes da entrega, não depois

Cada pedido recebe um identificador e é escrito num registo append-only, uma linha JSON por evento, *antes* de se tentar a notificação. A segunda linha, com o mesmo identificador, diz o que aconteceu de facto: `delivered` ou `failed`, com o motivo truncado a 300 caracteres. O diretório é criado com permissões `0700`, os ficheiros com `0600`, e o caminho é colocado deliberadamente fora do diretório de versão, para que o histórico sobreviva a uma publicação.

Verificação de aceitação executada após a publicação

Um script de verificação abre cada página de produto, em grupos de três, e falha se faltar o código 200, a âncora de perguntas, a âncora de exemplo ou o endereço canónico. Depois verifica o mapa do site — para não conter variantes de idioma que não se possam abrir e para conter cada produto — e `robots.txt`, para não bloquear os recursos necessários à renderização. Também falha se reaparecer na página conteúdo de um cliente antigo. É uma lista de coisas que já se estragaram uma vez.

Atualizações com gate, não com esperança

O script de publicação recusa-se a arrancar se o servidor tiver menos de 500 MB de memória livre, executa `npm audit --audit-level=high` e pára nas vulnerabilidades de nível alto se você não confirmar explicitamente, depois constrói a partir do zero — `.next` e `node_modules` apagados, instalação a partir do ficheiro de lock. Se o processo não aparecer `online` após o arranque, o script mostra as últimas 50 linhas do registo e sai com erro, em vez de reportar sucesso.

Reinício com limiares, não às cegas

O processo reinicia-se automaticamente acima de 500 MB de memória, com 4 segundos de atraso entre tentativas, aumento exponencial do atraso e paragem após 10 reinícios instáveis — para que um ciclo de falha se torne visível em vez de consumir o servidor em silêncio. Tempo de graça ao parar: 5 segundos, depois terminação forçada. Os registos têm data e fuso horário, num único fluxo.

Duplicados tratados, não contados duas vezes

A mesma pessoa, a mesma mensagem, duas vezes — um duplo clique, um recarregamento da página — produzia duas notificações idênticas para um único pedido. Agora a impressão digital `sha256` do par endereço + mensagem é mantida em memória por 10 minutos; o segundo envio recebe o mesmo identificador de pedido e a marca `duplicate`, e a notificação não se repete. Só são suprimidos os duplicados de uma entrega bem-sucedida; uma falhada pode voltar a passar.

Códigos de erro que dizem o que se partiu

400 para dados inválidos, 405 para método errado, 500 para corpo de pedido corrompido, 502 quando o canal de entrega respondeu mal, 503 quando faltam credenciais. A diferença conta às 3 da manhã: 502 significa "fornecedor", 503 significa "a nossa configuração". Ao visitante é dito de forma distinta "recebemos o pedido, mas não conseguimos notificar" — não um falso sucesso.

Retenção aplicada por código, não prometida na política

A nota de confidencialidade publicada diz que os pedidos do formulário são guardados durante 24 meses. O código aplica exatamente o mesmo número: `LEAD_RETENTION_DAYS` por defeito 730, e os ficheiros mais antigos do que o limite são eliminados a cada escrita, sem agendador que possa ser esquecido. O endereço IP é truncado para o prefixo de rede — `/24` em IPv4, `/48` em IPv6 — e lê-se o último salto no cabeçalho, não o primeiro, porque o primeiro é enviado pelo cliente.

Encontramos também o que ninguém reclamou

A mesma passagem pelo código revelou duas coisas que nenhum utilizador tinha assinalado: o limite de 10 pedidos por minuto podia ser contornado por completo, porque se lia o primeiro elemento no cabeçalho de endereços redirecionados — o controlado pelo cliente — e uma rota de iniciação de chamadas telefónicas estava aberta anonimamente, a nosso custo e a partir do nosso número, embora o componente que a usava já não estivesse montado em lado nenhum. Ambas foram corrigidas e verificadas em produção.

Qué aspecto tiene

El recorrido, paso a paso.

01

O inventário dos caminhos por onde um pedido chega a uma pessoa

A primeira entrega não é uma ferramenta, é uma lista: por onde passa um pedido desde o clique no botão até alguém o ler, o que quebra em cada passo e o que deve acontecer quando quebra. Neste site a lista tinha três elos e um era invisível.

02

A sonda e o registo, montados antes de qualquer outra coisa

Entregamos um endereço de saúde que verifica o caminho completo, não o processo, e o registo que escreve antes da entrega. A partir daqui, uma falha é uma pergunta com resposta, não uma escavação pelos registos. O endereço pode ser consultado a partir de qualquer serviço externo de monitorização, porque não devolve nada sensível.

03

A verificação de aceitação, escrita a partir de defeitos reais

Cada coisa que avariou uma vez entra no script de verificação executado depois da publicação. Não escrevemos testes para casos hipotéticos; escrevemos para os que já nos custaram. Entregamos o script, não apenas o resultado dele — você também o pode executar.

04

O ritmo de atualização e o gate antes da produção

Definimos o que é atualizado automaticamente, o que passa por verificação humana e o que não é tocado sem uma janela anunciada. O gate inclui a auditoria de segurança das dependências e a verificação de recursos do servidor, ambas executadas antes de tocar a produção.

05

A entrega, com a lista de faltas

No fim entregamos o procedimento de publicação, o procedimento de reversão, os endereços de saúde e a lista escrita do que não está coberto. Neste site, por exemplo, o ramo de expiração do pedido ao fornecedor está implementado e cai no mesmo tratamento que o erro de rede, mas o abort em si não foi provocado no teste — está escrito assim no registo de execução, não numa nota interna.

1Sonda care verificălivrarea până la unom2jurnalul scrisînainte de încercare3verificarea deacceptare rulată dupăfiecare publicareTrei piese, toate în depozitul acestui site.
O percurso, em 3 passos

Os dados

Qué tocamos, dónde están y cuánto se quedan

Las preguntas que hace cualquiera que tenga un delegado de protección de datos — hechas aquí antes de que las haga él.

Registo de pedidos
Nome, endereço de e-mail, telefone, empresa, serviço escolhido, mensagem, página de onde foi enviado, host da página de origem (apenas o host, não o endereço completo) e prefixo de rede do visitante. Ficheiros JSON por dia, no servidor próprio, fora do diretório de versão. Prazo: 24 meses, aplicado no momento da escrita.
Registos de processo e do servidor
A saída padrão e os erros do processo, com data e fuso horário, mais os registos do servidor web. Aqui vê-se uma falha silenciosa: os três erros de entrega do incidente de referência estavam no registo de erros, não em qualquer alerta. A rotação e o prazo são definidos para cada servidor; são dados técnicos, não conteúdo de conta.
O que nunca sai do servidor
Os tokens, os identificadores de canal e as chaves do fornecedor. A sonda de saúde responde exclusivamente com valores lógicos, precisamente para poder ser chamada por uma ferramenta externa sem divulgar nada. A mesma regra na notificação: a mensagem contém o identificador do pedido e a página, não credenciais.
Estatísticas de tráfego
A medição de tráfego passa pela ferramenta de análise configurada no projeto e é ativada após o consentimento. A definição real de retenção na conta de análise é um valor que lemos da conta, não um que assumimos — o registo de tratamentos deste site assinala-o explicitamente como elemento a clarificar, não como facto estabelecido.
Registo de tratamentos
Cada tipo de dados tocado pelo site tem uma entrada com finalidade, fundamento, categorias e prazo, num documento versionado juntamente com o código. Quando o código altera um prazo, o documento altera-se no mesmo commit — caso contrário a política e o programa dizem coisas diferentes, e quem se engana costuma ser o documento.

Un caso

Um formulário que entregou 500 em vez de leads, sete horas

A situação

Um site de apresentação com formulário de contacto, publicado recentemente. Todas as páginas respondem 200, o painel está verde, ninguém reclama nada. O único canal pelo qual um pedido chegava à equipa era uma notificação numa aplicação de mensagens.

Qué construimos

O token do bot de notificação tinha sido revogado; a interface do fornecedor respondia `401 Unauthorized`. A rota do formulário devolvia 500 e não escrevia nada. A primeira correção não foi o token, mas a ordem das operações: o pedido é agora escrito num registo append-only, com identificador próprio, *antes* de se tentar a entrega, e o resultado da entrega é acrescentado como segunda linha. Sobre isso montaram-se uma sonda pública de saúde que verifica o token e a possibilidade de escrita, códigos de erro distintos para „o fornecedor respondeu mal” e „faltam-nos credenciais”, um timeout de 10 segundos na entrega e a supressão de duplicados numa janela de 10 minutos. A mesma passagem pelo código removeu também um limite de pedidos que podia ser contornado, e uma rota de chamadas telefónicas deixada aberta anonimamente.

Qué salió

A sonda responde agora 200 com o token válido e o registo gravável; pode ser consultada a partir de qualquer serviço externo de monitorização, sem divulgar nada. Os testes em produção cobriram cada código de resposta — 400, 405, 500, 502, 503 — e duas submissões idênticas devolveram o mesmo identificador de pedido, a segunda marcada como duplicado, com duas linhas no registo, não quatro. Uma futura falha do canal de notificações já não apaga o pedido: fica no registo, com o motivo escrito.

Qué no dice el caso

A sonda diz que a entrega é possível agora, não que alguém leia as notificações. Quem as vê e em quanto tempo é uma decisão da equipa, não uma função do código. E o ramo de expiração do pedido ao fornecedor, embora implementado, não foi provocado no teste — cai no mesmo tratamento que o erro de rede, que foi testado; assinalamo-lo como não exercitado, não como verificado.

Perguntas

Lo que nos pregunta la gente antes de llamar

O que é que você monitoriza, concretamente?

O percurso de um pedido até uma pessoa, não a disponibilidade do servidor. `GET /api/health/contact` verifica, numa única chamada, duas coisas: que o token do canal de notificações continua válido — através de uma chamada real ao fornecedor, com timeout de 8 segundos — e que o registo de pedidos pode ser escrito. Responde 200 quando ambas são verdadeiras e 503 quando não são. Você pode chamá-lo já neste site: é público, precisamente porque não devolve mais do que valores lógicos.

Porque é que um formulário cairia sem que ninguém reparasse?

Porque a parte visível continua a funcionar. A página carrega, o botão responde, o servidor devolve 200 em todas as páginas — só se rompe a ligação final, que não tem interface. Neste site, o token do bot de notificações foi revogado: o fornecedor respondia `401 Unauthorized`, a rota devolvia 500, e o pedido não era escrito em lado nenhum. Três falhas reais em aproximadamente sete horas, visíveis apenas no registo de erros do processo. Por isso o registo é agora escrito antes da entrega: mesmo que a notificação falhe, o pedido existe.

O que acontece se a notificação falhar depois de você ter reparado?

O pedido já está escrito no registo com um identificador próprio, e a segunda linha do registo diz `failed` e o motivo. O visitante recebe uma resposta distinta — “recebemos o pedido, mas não foi possível notificar” — não um sucesso falso. O código de resposta diferencia a causa: 502 significa que o fornecedor respondeu mal, 503 que faltam credenciais nossas. Às 3 da manhã, a diferença entre os dois decide se você telefona a alguém ou não.

Você atualiza automaticamente as dependências?

Não sem gate. A publicação executa `npm audit` ao nível `high` e para em vulnerabilidades deste nível se a continuação não for confirmada explicitamente; verifica primeiro também a memória disponível do servidor, com limite de 500 MB, porque uma construção iniciada num servidor limitado deixa a aplicação parada. A construção é feita a partir de um estado limpo: o diretório de construção e as dependências são apagados, a instalação é feita a partir do ficheiro de bloqueio. O que é atualizado automaticamente e o que passa por verificação humana é definido por projeto, não implicitamente.

Como é que vocês sabem que uma publicação não estragou outra coisa?

Através de um script de verificação executado após a publicação, que abre cada página de produto e falha se faltar o código 200, a âncora das perguntas, a âncora do exemplo ou o endereço canónico. Em seguida, verifica o mapa do site — para conter cada produto e não conter variantes de idioma que não possam ser abertas — e o `robots.txt`, para não bloquear recursos de renderização. Cada verificação da lista corresponde a algo que já se estragou uma vez. O script é entregue juntamente com o projeto.

O que fazem quando a aplicação bloqueia ou consome memória?

O processo é reiniciado automaticamente acima do limiar de 500 MB, com 4 segundos de atraso entre tentativas e aumento exponencial, mas pára após 10 reinícios instáveis num intervalo curto. Isto é importante: um loop de queda que se reinicia infinitamente parece saudável num painel e consome o servidor em silêncio. Preferimos que o processo fique parado e visível.

Durante quanto tempo guardam os dados do formulário e quem os pode ler?

24 meses, aplicados pelo código, não apenas declarados: o limiar é uma variável com o valor predefinido de 730 dias, e os ficheiros mais antigos são apagados a cada nova gravação, sem agendador que possa ser esquecido. O diretório tem permissões `0700`, os ficheiros `0600`, e o caminho fica fora do diretório de versão, para que o histórico sobreviva à publicação. O endereço IP não é guardado por inteiro: é truncado para `/24` no IPv4 e `/48` no IPv6, lendo o último hop do cabeçalho, não o primeiro — o primeiro é enviado pelo cliente e não significa nada.

Encontram também problemas que nós não reclamámos?

Acontece, e normalmente esses são os caros. A mesma passagem pelo código que reparou o formulário revelou duas coisas que ninguém tinha assinalado: o limite de pedidos podia ser contornado por completo, porque se lia o primeiro elemento do cabeçalho de endereços redirecionados — precisamente o que o cliente envia; e uma rota que iniciava chamadas telefónicas estava aberta anonimamente, à nossa custa, embora o componente que a usava já tivesse sido desmontado. Ambos foram reparados e verificados em produção. O que não podemos prometer é que encontremos tudo; o que podemos prometer é que reportamos também o que vocês não pediram.

O que é que a manutenção não cobre?

Não é um serviço de segurança com monitorização contínua e não é um centro de operações. Não garantimos uma percentagem de disponibilidade sem uma medição que a sustente — e, para que fique claro, neste momento não publicamos uma cifra dessas para o nosso próprio site. Não assumimos a responsabilidade por uma plataforma de terceiros a que não temos acesso. E não tratamos uma página que responde 200 como prova de que está tudo a funcionar: foi exatamente esse o problema a partir do qual começou tudo o que está escrito acima.

Em que se baseiam as afirmações acima (13 fontes)
  1. A sonda de entrega responde 200 em produção: `{"ok":true,"telegram":{"configured":true,"credentialsValid":true},"leadJournal":{"writable":true}}`https://www.megapromoting.com/api/health/contact · 2026-09-06
  2. Cabeçalhos de segurança ativos em produção: HSTS `max-age=63072000; includeSubDomains; preload`, `X-Content-Type-Options: nosniff`, `X-Frame-Options: SAMEORIGIN`, `Referrer-Policy: strict-origin-when-cross-origin`, `Permissions-Policy` com `microphone=(self)`https://www.megapromoting.com/servicii · 2026-09-06

11 delas são código e ficheiros dos nossos repositórios. Não publicamos o nome nem a linha: juntos, numa única página, descreveriam com demasiada precisão como estão construídos sistemas que não são só nossos. Percorremo-los consigo, no repositório, a pedido — a verificação continua possível, só que se faz numa conversa.

O que gostaria que funcionasse melhor?

Conte-nos o seu processo. Em conjunto decidimos o que vale a pena construir, o que podemos ligar e como verificamos o resultado.

Vamos falar