Caderno de engenhariaEngenheiro de software

Software, produto e as decisões entre os dois.

Quando uma escala vira matemática

Construindo um motor com CP-SAT: regras humanas, restrições matemáticas e uma decisão que continua sendo de quem usa.

Ler no site →

Outras leituras

Nota técnica · IA aplicada

O que um HTTP 200 não conta

Uma resposta pode chegar com sucesso e ainda carregar uma falha. Esse é o problema por trás do Jev Resilience.

Nota · Formação

Profundidade técnica, visão de produto

O que aproxima arquitetura cloud e Product Ownership na minha formação.

Projetos

Do texto ao que funciona.

Interfaces reais, código e decisões que sustentam os produtos.

01 / Produto web · Educação clínica

Diagnostique

Um jogo diário de raciocínio clínico em português. Pistas progressivas, até seis tentativas e um arquivo de casos anteriores.

Tela real do Diagnostique: pista inicial e pistas seguintes bloqueadas.
01Detalhe da interface realCapturas de 21 out. 2026Ampliar imagem

Decisão 01

Revelar uma pista também é uma decisão de API.

A interface em React e TypeScript acompanha as tentativas. O backend em Fastify decide quais informações a sessão pode receber a cada passo.

A resposta inicial traz as pistas liberadas e o total de pistas. A resposta correta e a explicação ficam fora desse estado.

Representação editorial do fluxo implementado
O que o teste verifica

O teste de serialização compara as pistas retornadas com o recorte liberado e verifica a ausência da resposta, da explicação e de uma pista futura. É uma evidência de contrato no código; não uma métrica de uso.

↑ Voltar à evidência
Arquivo real de casos do Diagnostique.
02Arquivo de casosCapturas de 21 out. 2026Ampliar imagem

Decisão 02

O histórico mantém sua referência.

No SQLite, definições de conteúdo têm revisões. Uma publicação referencia uma dessas revisões, preservando o contexto em que uma sessão começou.

Os testes de conteúdo verificam que uma edição cria uma nova revisão sem substituir a definição histórica e que publicações anteriores mantêm sua referência.

A relação preservada

Os testes cobrem tanto a definição histórica quanto o vínculo entre publicação e revisão. A captura do arquivo dá contexto ao histórico; a prova dessa consistência está na implementação e nos testes.

Trade-off. Preservar revisões mantém a consistência, mas exige distinguir definição, revisão e publicação. Atualizar o conteúdo deixa de ser uma simples substituição do registro anterior.

Casos fictícios, com finalidade educativa.

02 / Código aberto · Confiabilidade

Jev Resilience

Um starter Spring Boot para detectar falhas semânticas em respostas de serviços WebFlux.

Fixture de teste · não é tráfego de produção
{
  "status": "ok",
  "note": "system under maintenance"
}
01Payload usado no teste offline do cliente de avaliação.Ver a fonte · Abre em outra aba

Decisão 01

A avaliação entra na composição reativa.

O aspecto compõe a avaliação no Mono ou Flux retornado. O item segue ou dá lugar a SemanticFailureException. A chamada é não bloqueante; isso não significa latência zero.

Trecho da implementação pública
return jevEvaluationService.evaluateSilentFailure(payload)
    .flatMap(score -> {
        if (score > threshold) {
            return Mono.<T>error(
                new SemanticFailureException(score, payload));
        }
        return Mono.just(item);
    });
Método screen · trecho real, com formatação ajustada.Ver a fonte · Abre em outra aba
Teste offline existente
server.enqueue(new MockResponse()
    .setResponseCode(500).setBody("boom"));

Double score = service
    .evaluateSilentFailure("irrelevant payload").block();

assertThat(score).isEqualTo(0.0);
02failsOpenWhenServerErrors · teste com resposta simulada do avaliador.Ver a fonte · Abre em outra aba

Decisão 02

Falhar aberto é uma escolha explícita.

O teste configura uma resposta 500 do avaliador e espera um score de 0.0. O serviço também aplica timeout e onErrorReturn(0.0). Esse 500 pertence à dependência simulada, não ao transporte do serviço original.

A implementação do fallback

O fallback evita transformar indisponibilidade do avaliador em uma falha da aplicação. Quando o score supera o limite, o aspecto emite a exceção; no fallback, o score é 0.0.

.timeout(properties.getTimeout())
.map(response -> extractScore(response, properties.getQuestionKey()))
.doOnError(error -> log.warn(
    "Jev evaluation failed, failing open (treating payload as valid): {}",
    error.toString()))
.onErrorReturn(0.0);
Ver a fonte · Abre em outra aba

Trade-off. O fail-open preserva continuidade, mas pode deixar uma falha semântica passar quando o avaliador está indisponível. A avaliação externa também acrescenta latência, custo e uma dependência operacional.

Os trechos mostram código e fixtures reais do repositório. Não representam tráfego de produção, benchmarks ou uma execução de testes nesta página.

Vicente Damasceno

Quem escreve e constrói.

Sou Vicente Damasceno, engenheiro de software. Trabalho com backend e produtos web, conectando Java, Spring Boot, React e cloud a problemas de produto. Exploro IA aplicada como parte de sistemas, com atenção aos seus limites e custos.

Marcos

Cloud e produto, na mesma conversa.

AWS Certified Solutions Architect – Associate
Arquitetura cloud como parte da formação técnica. Ver a fonte · Abre em outra aba
Professional Scrum Product Owner II
Profundidade técnica acompanhada de visão de produto e negócio. Ver a fonte · Abre em outra aba

Capturas do Diagnostique