Logs e Auditoria — Especificação (v1.0)
Documentos desta funcionalidade: 01 - Definição (v1.0) · 02 - Especificação (v1.0) · 03 - Protótipo (v1.0, código em 03 - Protótipo v1.0.html) · 04 - Mapeamento de Banco de Dados (v1.0) · Cenários de Teste (v1.0) · 05 - Registro de Decisões (v1.0)
Rascunho v1.0. Itens sem origem em decisão do solicitante, DDL, SBIS ou documento do projeto estão marcados [PROPOSTA]. Revisão por Dois Críticos pendente.
2.1 Premissa de design
O desenvolvedor não deve precisar lembrar de registrar. O caminho padrão registra; o caminho de exceção exige justificativa escrita ([NotAudited("motivo")]) e é visível em revisão. O usuário final só enxerga um código de suporte; o auditor só enxerga uma linha do tempo.
2.2 Histórias de usuário
| ID | Como… | Quero… | Para… |
|---|---|---|---|
| US-LOG-01 | Suporte | ver tudo que aconteceu com um usuário em um intervalo, a partir do código de suporte | achar a causa de um problema pontual |
| US-LOG-02 | Suporte | ver a saúde geral (erros, lentidão, falhas de banco, por cliente quando for o banco) | perceber anomalias antes do cliente |
| US-LOG-03 | Usuário clínico | receber, no erro, uma mensagem simples com um código | informar ao suporte sem termos técnicos |
| US-LOG-04 | Auditor | consultar a trilha em ordem cronológica | saber quem fez o quê |
| US-LOG-05 | Auditor | filtrar por período, evento, usuário e registro afetado (paciente) | investigar um caso |
| US-LOG-06 | Auditor | exportar o resultado em formato aberto | entregar evidência ao certificador |
| US-LOG-07 | Sistema | registrar abertura de prontuário e consultas | cumprir NGS1.07.03a |
| US-LOG-08 | Sistema | registrar criação, alteração e inativação com os nomes dos campos | rastrear escrita sem guardar valores |
| US-LOG-09 | Sistema | registrar eventos de segurança no repositório global | cumprir NGS1.07.03b/c |
| US-LOG-10 | Desenvolvedor | declarar a auditoria de um endpoint com um atributo | incorporar sem esforço |
| US-LOG-11 | Desenvolvedor | ser avisado por build, inicialização e CI quando faltar | não esquecer |
| US-LOG-12 | Administrador | conceder o direito de visualizar a auditoria a um perfil | limitar o acesso (NGS1.07.02) |
2.3 Descrição funcional
2.3.1 Log de sistema
- Pacote
Gemed.Telemetry[PROPOSTA]:AddGemedTelemetry()configura OpenTelemetry (.NET SDK),ILoggercom saída JSON, middleware detraceIde enriquecimento do contexto (tenant, clínica, usuário). - Fluxo: aplicação → OTel Collector (redação, buffer, roteamento) → Loki (logs), Prometheus (métricas) e, opcionalmente, Tempo.
- Rótulos do Loki:
service,environment,level. Os demais campos são metadados estruturados (RN-LOG-006). - Métricas (RN-LOG-007):
gemed_http_request_duration_seconds{endpoint,status_class}sem tenant;gemed_tenant_requests_total{tenant,status_class};gemed_db_connection_failures_total{tenant};gemed_db_query_duration_seconds{tenant};gemed_db_timeouts_total{tenant}. Nomes [PROPOSTA]. - Dashboards [PROPOSTA]: “Um usuário” (entrada:
traceIdouuserId; mostra a sequência de requisições, erros e tempos) e “Saúde geral” (taxa de erro por serviço, latência por endpoint, falhas de banco por tenant). - Alertas [PROPOSTA]: taxa de erro 5xx acima do limiar por serviço; falha de conexão de banco de qualquer tenant; latência p95 acima do limiar; ausência de logs de um serviço. Limiares após medir volume.
- Eventos catalogados:
SYS-<área>-<nnn>. Primeiro:SYS-TRD-001(tradução ausente, DT-011). Geração por[LoggerMessage].
2.3.2 Trilha de auditoria
- Pacote
Gemed.Audit[PROPOSTA]:AddGemedAudit(),IAuditTrail,[Audited],[NotAudited],AuditEventType, interceptador de gravação, analisador Roslyn. - Captura de leitura:
[Audited(AuditEventType.RegistroConsulta, recurso: "Prontuario")]no endpoint ou caso de uso; o comportamento de pipeline lê o identificador do registro afetado do resultado ou da rota. - Captura de escrita:
SaveChangesInterceptordo EF Core grava, na mesma transação, um evento por entidade alterada com os nomes dos campos alterados. Sem EF Core: decorador do repositório (P-LOG-05). - Captura de segurança:
IAuditTrail.Record(tipo, usuário, complemento)chamada pelo serviço de segurança. - Supressão: por tipo de evento, com
INSERT … WHERE NOT EXISTSsobre a chave (usuário, tipo, registro, janela) (RN-LOG-020). - Integridade, fase 1:
hash_linha = SHA-256(campos canônicos)calculado pela aplicação; papel de banco só com INSERT e SELECT (RN-LOG-013, 025).
2.3.3 Catálogo de eventos (AuditEventType)
Repositório: G = global (IpSeguranca), C = por cliente. Falha fechada: S = sim. Atribuição de repositório e janelas são [PROPOSTA]; o item NGS vem do requisito.
| Código | Evento | Categoria | NGS | Repo | Falha fechada | Supressão |
|---|---|---|---|---|---|---|
| AUD-RES-001 | Criação de registro do RES | Clínica | 07.03a | C | S | não |
| AUD-RES-002 | Duplicação de registro do RES | Clínica | 07.03a | C | S | não |
| AUD-RES-003 | Consulta de registro do RES (abertura de prontuário) | Clínica | 07.03a | C | S | um por abertura e por usuário/paciente na janela (parâmetro) |
| AUD-RES-004 | Inativação de registro do RES | Clínica | 07.03a | C | S | não |
| AUD-RES-005 | Alteração de registro do RES (nomes dos campos) | Clínica | 07.03a (implícito) | C | S | não |
| AUD-RES-006 | Importação de dados | Clínica | 07.03a | C | S | não |
| AUD-RES-007 | Exportação de dados | Clínica | 07.03a | C | S | não |
| AUD-RES-008 | Impressão de registro do RES | Clínica | 07.03a | C | S | não |
| AUD-RES-009 | Solicitação de acesso de emergência (reservado) | Clínica | 07.03a / 11.07 | C | S | não |
| AUD-RES-010 | Registro ou alteração de termo de consentimento | Clínica | 07.03a | C | S | não |
| AUD-RES-011 | Regra de apoio à decisão clínica (criar, inativar, alterar) | Clínica | 07.03a | C | S | não |
| AUD-RES-012 | Validação de registro de preceptoria | Clínica | 07.04a | C | S | não |
| AUD-USR-001 | Autenticação com sucesso | Operacional | 07.03b | G | S | não |
| AUD-USR-002 | Autenticação sem sucesso | Operacional | 07.03b | G | S | não |
| AUD-USR-003 | Troca de senha | Operacional | 07.03b | G | S | não |
| AUD-USR-004 | Assinatura digital realizada | Clínica | 07.03b | C | S | não |
| AUD-USR-005 | Validação de assinatura digital | Clínica | 07.03b | C | S | não |
| AUD-USR-006 | Falha de assinatura ou de validação | Clínica | 07.03b | C | S | não |
| AUD-USR-007 | Solicitação de esquecimento | Operacional | 07.03b | C | S | não |
| AUD-USR-008 | Encerramento ou bloqueio de sessão | Operacional | 07.04b | G | S | não |
| AUD-USR-009 | Desbloqueio de sessão | Operacional | 07.04b | G | S | não |
| AUD-USR-010 | Aceitação do termo de uso | Operacional | 07.04b | G | S | não |
| AUD-OPE-001 | Gestão de usuários e perfis (criar, alterar, inativar/bloquear, ativar/desbloquear) | Operacional | 07.03c | G | S | não |
| AUD-OPE-002 | Cópia de segurança e restauração | Operacional | 07.03c | C | S | não |
| AUD-OPE-003 | Configuração do sistema | Operacional | 07.04c | G ou C, conforme o parâmetro | S | não |
| AUD-OPE-004 | Geração de senha para usuário | Operacional | 07.04c | G | S | não |
| AUD-OPE-005 | Acesso aos registros de auditoria (consulta e exportação) | Operacional | 07.04c | G | S | não |
| AUD-OPE-006 | Erro de processo operacional, com descrição | Operacional | 07.04c | C | não | não |
| AUD-OPE-010 | Criação, alteração ou inativação de cadastro fora do RES | Operacional | — (decisão do solicitante: auditoria no sistema todo) | C | S | não |
Evento de preceptoria, revogação de certificado (NGS2) e demais itens “quando contemplados pelo sistema” entram no catálogo quando a funcionalidade existir. A matriz de conformidade NGS1.07.03/.04 é gerada a partir desta enumeração.
2.3.4 Campos do registro (NGS1.07.05)
Identificador único; data e hora UTC; tipo de evento; categoria; componente e IP; usuário (GUID global em G; GUID global também em C, mapeável ao IdUsuario local); identificador do registro afetado (IdPaciente quando houver; recurso e id do recurso nos demais casos); tenant (ClienteBDId); informação complementar (JSON, sem valores clínicos); hash_linha. Detalhe de tipos na seção 4.
2.3.5 Tela do auditor
Rota e menu no contexto Segurança [PROPOSTA]: “Auditoria”. Lista cronológica (mais recente primeiro) com colunas Data e hora, Evento, Usuário, Registro afetado, Origem (IP/componente), Categoria; filtros por período (obrigatório, limite de intervalo por parâmetro), evento (seleção múltipla do catálogo), usuário (autocomplete por nome, filtro pelo GUID) e registro afetado (autocomplete de paciente por nome ou prontuário, filtro pelo IdPaciente). O detalhe abre em painel lateral. Exportar respeita os filtros. Protótipo em 03.
2.3.6 Salvaguardas para o desenvolvedor
- Analisador Roslyn (erro de build): endpoint ou caso de uso sem
[Audited]nem[NotAudited("motivo")];[NotAudited]sem motivo; entidade clínica sem cobertura do interceptador. - Varredura na inicialização: percorre
EndpointDataSourcee derruba a aplicação listando os endpoints sem declaração. - Teste de arquitetura (NetArchTest) no CI: controladores e casos de uso declaram o atributo; ninguém referencia o
DbContextfora do ponto autorizado. - Dependência obrigatória: a aplicação não inicia sem
AddGemedAudit()eAddGemedTelemetry(). - Template
dotnet new gemed-apijá traz tudo configurado. - Biblioteca de Schema: estender a detecção de “tabelas sem o padrão dos 16 campos” para exigir cobertura de auditoria nas tabelas clínicas.
2.4 Critérios de aceite
| ID | Critério | US | RN |
|---|---|---|---|
| CA-LOG-001.1 | Dado um erro 500 em uma requisição, então a resposta ao usuário traz mensagem não técnica e o traceId como código, e o log de sistema tem o mesmo traceId | US-LOG-03 | RN-LOG-004 |
| CA-LOG-001.2 | Dado o traceId, então o dashboard “Um usuário” mostra a sequência das requisições do usuário no intervalo | US-LOG-01 | RN-LOG-002 |
| CA-LOG-002.1 | Dado qualquer registro do log de sistema, então não contém nome, CPF, prontuário nem valor clínico | US-LOG-01 | RN-LOG-003 |
| CA-LOG-002.2 | Dado o Loki, então os rótulos são apenas service, environment e level | US-LOG-02 | RN-LOG-006 |
| CA-LOG-003.1 | Dada falha de conexão com o banco de um tenant, então a métrica de banco com tenant aumenta e o alerta dispara | US-LOG-02 | RN-LOG-007, 008 |
| CA-LOG-004.1 | Dado o Collector indisponível, então a operação do usuário conclui e o log é reenviado depois | US-LOG-01 | RN-LOG-010 |
| CA-LOG-005.1 | Dada a abertura de um prontuário, então há exatamente um evento AUD-RES-003 com o IdPaciente e sem nome, CPF ou prontuário | US-LOG-07 | RN-LOG-015, 019 |
| CA-LOG-005.2 | Dada nova abertura do mesmo prontuário pelo mesmo usuário dentro da janela de supressão, então nenhum novo evento é gravado | US-LOG-07 | RN-LOG-020 |
| CA-LOG-006.1 | Dada a alteração de um registro clínico, então o evento lista os nomes dos campos alterados e nenhum valor | US-LOG-08 | RN-LOG-016 |
| CA-LOG-006.2 | Dada falha na gravação do evento clínico, então a operação inteira é desfeita e o usuário vê mensagem com código | US-LOG-08 | RN-LOG-014 |
| CA-LOG-007.1 | Dada tentativa de login inválida, então há evento AUD-USR-002 em IpSeguranca, sem a senha | US-LOG-09 | RN-LOG-012 |
| CA-LOG-007.2 | Dada a troca de senha, o bloqueio de conta e a gestão de perfil, então há evento no repositório global | US-LOG-09 | RN-LOG-012 |
| CA-LOG-008.1 | Dado o papel de banco da aplicação, então UPDATE, DELETE e TRUNCATE na trilha são recusados | US-LOG-04 | RN-LOG-013 |
| CA-LOG-008.2 | Dada uma linha da trilha, então o hash_linha confere com o recálculo dos campos | US-LOG-04 | RN-LOG-025 |
| CA-LOG-009.1 | Dado um usuário sem o direito de auditoria, então a rota e a API retornam acesso negado | US-LOG-12 | RN-LOG-022 |
| CA-LOG-009.2 | Dada qualquer consulta ou exportação da trilha, então há evento AUD-OPE-005 | US-LOG-04 | RN-LOG-022 |
| CA-LOG-010.1 | Dada a consulta com período, então a lista vem em ordem cronológica e mescla os repositórios global e do cliente | US-LOG-04 | RN-LOG-012, 023 |
| CA-LOG-010.2 | Dados filtros de evento, usuário e registro afetado, então só voltam eventos que atendem a todos | US-LOG-05 | RN-LOG-023 |
| CA-LOG-010.3 | Dado um evento antigo (fora da retenção quente, se houver), então ele continua visível na lista | US-LOG-04 | RN-LOG-023 |
| CA-LOG-011.1 | Dada a exportação, então o arquivo é CSV ou JSON, com software e instituição (nome, CNES, CNPJ) no cabeçalho e datas em RFC 3339 | US-LOG-06 | RN-LOG-024 |
| CA-LOG-012.1 | Dado um endpoint sem [Audited] nem [NotAudited], então o build falha | US-LOG-11 | RN-LOG-021 |
| CA-LOG-012.2 | Dado o mesmo endpoint em um build que passou por fora, então a aplicação não inicia e lista o endpoint | US-LOG-11 | RN-LOG-021 |
| CA-LOG-012.3 | Dada a aplicação sem AddGemedAudit(), então não inicia | US-LOG-11 | RN-LOG-021 |
| CA-LOG-013.1 | Dados relógios dos componentes, então os instantes gravados são UTC | US-LOG-04 | RN-LOG-027 |
2.5 Fluxos de exceção
| ID | Situação | Comportamento | Recuperação |
|---|---|---|---|
| EX-LOG-01 | Falha ao gravar evento de falha fechada | Operação desfeita; mensagem LOG-EMSG-06 com código; log de sistema nível Error com SYS-AUD-001 | Usuário repete; suporte vê o motivo pelo traceId |
| EX-LOG-02 | Falha ao gravar AUD-OPE-006 (falha aberta) | Operação segue; evento vai ao log de sistema (SYS-AUD-002) | Suporte reprocessa se necessário |
| EX-LOG-03 | Collector ou Loki indisponíveis | Buffer local; reenvio; alerta de ausência de logs | Automática |
| EX-LOG-04 | Auditor sem direito | Acesso negado (LOG-EMSG-02); evento de tentativa fica no log de sistema | Administrador concede o direito |
| EX-LOG-05 | Período inválido ou acima do limite | LOG-EMSG-03; nada é consultado | Usuário ajusta o período |
| EX-LOG-06 | Consulta sem resultados | LOG-EMSG-04 | Usuário ajusta os filtros |
| EX-LOG-07 | Repositório global ou do cliente indisponível na consulta | Mostra o que veio, com aviso de que um repositório não respondeu (LOG-EMSG-07) | Tentar novamente |
| EX-LOG-08 | Exportação muito grande | Gerada em segundo plano; LOG-EMSG-05 ao concluir | Baixar quando pronta |
| EX-LOG-09 | Paciente unificado (merge) | Consulta por IdPaciente usa a tabela de equivalência | — |
2.6 Validações
Período obrigatório, início anterior ao fim, intervalo máximo por parâmetro; evento deve existir no catálogo; usuário e registro afetado por identificador válido; exportação só nos formatos oferecidos. Toda validação ocorre na API (a interface só orienta).
2.7 Componentes de interface
Cabeçalho da tela; barra de filtros (período, evento, usuário, registro afetado) com chips dos filtros ativos; lista cronológica com rolagem por cursor; painel de detalhe; botão primário “Exportar” (um por região, Design System 12); aviso de repositório indisponível; estado vazio. Ícones Lucide [PROPOSTA]: shield-check (menu), filter, download, user, file-text, clock, triangle-alert. Tokens do Design System; sem cores fixas; tema claro e escuro.
2.8 Integração com backend [PROPOSTA]
| Método e rota | Função |
|---|---|
GET /api/auditoria/eventos?de&ate&evento[]&usuarioId®istroId&categoria&cursor&limite | Lista mesclada e cronológica |
GET /api/auditoria/eventos/{id} | Detalhe (campos alterados, componente, IP) |
GET /api/auditoria/tipos-evento | Catálogo para o filtro |
POST /api/auditoria/exportacoes (formato, filtros) | Gera a exportação; devolve o arquivo ou um identificador |
GET /api/auditoria/exportacoes/{id} | Situação e download |
Todos exigem o direito “Visualizar auditoria” (4.6) e geram AUD-OPE-005. A API consulta os dois repositórios e mescla por ocorrido_em, id.
2.9 Catálogo de mensagens (i18n)
| ID | Tipo | pt-BR | en-US | es-419 |
|---|---|---|---|---|
| LOG-EMSG-01 | Erro | Algo deu errado. Informe ao suporte o código {codigo}. | Something went wrong. Give support the code {codigo}. | Algo salió mal. Informe al soporte el código {codigo}. |
| LOG-EMSG-02 | Erro | Você não tem permissão para ver a auditoria. | You don’t have permission to view the audit trail. | No tiene permiso para ver la auditoría. |
| LOG-EMSG-03 | Erro | Informe um período válido, com início antes do fim e até {dias} dias. | Enter a valid period, start before end, up to {dias} days. | Indique un período válido, con inicio antes del fin y hasta {dias} días. |
| LOG-EMSG-04 | Vazio | Nenhum evento encontrado para os filtros escolhidos. | No events found for the selected filters. | No se encontraron eventos con los filtros elegidos. |
| LOG-EMSG-05 | Info | Exportação pronta para baixar. | Export ready to download. | Exportación lista para descargar. |
| LOG-EMSG-06 | Erro | Não foi possível concluir a operação. Informe ao suporte o código {codigo}. | The operation could not be completed. Give support the code {codigo}. | No fue posible completar la operación. Informe al soporte el código {codigo}. |
| LOG-EMSG-07 | Aviso | Parte dos registros não pôde ser consultada. Tente novamente. | Some records could not be retrieved. Try again. | No se pudo consultar parte de los registros. Intente de nuevo. |
Rótulos da tela (Auditoria, Data e hora, Evento, Usuário, Registro afetado, Origem, Categoria, Clínica, Operacional, Exportar, Período, Filtros) seguem o mesmo padrão nos três idiomas e entram no dicionário de termos. ECF.17.18: pt-BR obrigatório.
2.10 Acessibilidade
Foco e estados de campo pelo Design System (seções 11 e 12); erro nunca só por cor; lista navegável por teclado; painel de detalhe com foco gerenciado e fechamento por Esc; tabelas com cabeçalhos associados; área tocável mínima de 44x44 px; mobile first (a lista vira cartões).
2.11 Conformidade SBIS
| Requisito | Est. | Como é atendido | Onde |
|---|---|---|---|
| NGS1.07.01 | 1 | Trilha contínua, sem desligamento; pacote obrigatório | RN-LOG-013, 021 |
| NGS1.07.02 | 1 | Somente inserção; consulta restrita a auditor e administrador; selo adiado e a confirmar (P-LOG-06) | RN-LOG-013, 022, 025 |
| NGS1.07.03 | 1 | Catálogo AUD-RES, AUD-USR, AUD-OPE; matriz gerada | 2.3.3 |
| NGS1.07.04 | 2 | Eventos avançados já no catálogo (AUD-RES-012, USR-008 a 010, OPE-003 a 006) | 2.3.3 |
| NGS1.07.05 | 1 | Campos do registro | 2.3.4 |
| NGS1.07.06 | 1 | ID opaco e nomes de campos; interpretação a confirmar (P-LOG-01) | RN-LOG-015, 016 |
| NGS1.07.07 | 1 | Tela cronológica com filtros; todos os registros visíveis | RN-LOG-023 |
| NGS1.07.08 | 3 | Exportação CSV/JSON com identificação | RN-LOG-024 |
| NGS1.02.13 | 1 | Tentativas de login auditadas (a regra de bloqueio é do contexto Segurança) | AUD-USR-002 |
| NGS1.03.01 | 1 | Direito de visualização por perfil | RN-LOG-022 |
| NGS1.08.06 | 1 | Relógios em UTC; item no manual de operação | RN-LOG-027 |
| NGS1.09.02 | 1 | RFC 3339 na exportação | RN-LOG-024 |
| NGS1.11.07 | 3 | Evento reservado; funcionalidade futura | RN-LOG-029 |
| ECF.17.19 | 1 | Mensagem simples com código; sem conteúdo técnico | RN-LOG-004 |