Pular para o conteúdo
Jonas Moura~/bancada
sessão TX9EJjxE… Portfólio
Dados fictícios. Simulação educacional: não é dispositivo médico e não deve ser usada em decisão clínica.

Painel técnico

Tudo que está por trás

using System; using System.Collections.Generic; using System.Globalization; using System.Security.Cryptography; using System.Text; namespace Bancada.Dominio; /// <summary> /// Cadeia de hash da auditoria (vault: Auditoria-Encadeada). Cada evento guarda /// SHA-256(hashAnterior + "\n" + conteúdo canônico); alterar, remover ou trocar a ordem de um evento antigo quebra os seguintes. /// </summary> public static class CadeiaDeAuditoria { public static string HashGenesis { get; } = Sha256("BANCADA-GENESIS"); public static string Canonico(EventoDeAuditoria e) => string.Join( '|', e.Seq.ToString(CultureInfo.InvariantCulture), e.Quando.UtcDateTime.ToString("yyyy-MM-dd'T'HH:mm:ss.fff'Z'", CultureInfo.InvariantCulture), Escapar(e.Papel), Escapar(e.Operador), Escapar(e.Acao), Escapar(e.AlvoTipo), Escapar(e.AlvoId), Escapar(e.DetalheJson), Escapar(e.Resultado)); /// <summary>Devolve uma cópia do evento com os hashes preenchidos, ligada ao evento anterior.</summary> public static EventoDeAuditoria Encadear(string hashAnterior, EventoDeAuditoria e) => new() { Seq = e.Seq, Quando = e.Quando, Papel = e.Papel, Operador = e.Operador, Acao = e.Acao, AlvoTipo = e.AlvoTipo, AlvoId = e.AlvoId, DetalheJson = e.DetalheJson, Resultado = e.Resultado, HashAnterior = hashAnterior, Hash = Calcular(hashAnterior, e), }; /// <summary>Confere a cadeia inteira. Devolve o seq do primeiro elo quebrado, ou nulo se estiver íntegra.</summary> public static int? PrimeiroEloQuebrado(IReadOnlyList<EventoDeAuditoria> eventos) { var anterior = HashGenesis; foreach (var e in eventos) { if (e.HashAnterior != anterior || e.Hash != Calcular(anterior, e)) { return e.Seq; } anterior = e.Hash; } return null; } private static string Calcular(string hashAnterior, EventoDeAuditoria e) => Sha256(hashAnterior + "\n" + Canonico(e)); private static string Escapar(string campo) => campo.Replace("\\", "\\\\", StringComparison.Ordinal).Replace("|", "\\|", StringComparison.Ordinal); private static string Sha256(string texto) => Convert.ToHexStringLower(SHA256.HashData(Encoding.UTF8.GetBytes(texto))); }

Ajuda · Painel técnico

O painel técnico: arquitetura, cobertura de testes, protocolos e o executor que roda os testes de verdade.

Como fazer

  1. Navegue pelas abas
  2. Veja a cobertura de linhas e ramos
  3. Rode os testes e acompanhe a saída ao vivo
Vídeo de exemplo, sem áudio