Governança de alertas (combate à fadiga)
A SauBit emite alertas clínicos determinísticos (clinical_alerts) além das interações
fármaco-fármaco. Em ambientes reais, o excesso de alertas leva à fadiga: o profissional
passa a ignorar avisos — inclusive os críticos. A governança de alertas permite que cada
organização ajuste o que é exibido sem nunca alterar a verdade clínica.
Princípios de segurança
- Supressão é apresentação, não diagnóstico. Um alerta suprimido da lista visível
continua contando para o
prescription_risk_level. A governança nunca rebaixa o risco da prescrição. - Risco crítico não pode ser ocultado. Alertas no nível
confirm_min_severityou acima (padrão:CONTRAINDICADO) são sempre exibidos e marcados comrequires_confirmation: true— nenhuma regra de política consegue suprimi-los. - Toda supressão é auditável. Cada item suprimido carrega o motivo (
suppression_reason) e, em overrides de alertas conhecidos, a justificativa textual registrada.
Campos na resposta
Cada item de clinical_alerts expõe:
| Campo | Descrição |
|---|---|
id | Identificador estável do alerta (independente da ordem dos fármacos). Use para suprimir/justificar alertas conhecidos. |
requires_confirmation | true quando o alerta exige confirmação explícita antes de prosseguir. |
E a resposta ganha o bloco alert_governance:
"alert_governance": {
"applied": true,
"policy_enabled": true,
"view": "pharmacist",
"unit": "icu",
"min_severity": "MODERADO",
"confirm_min_severity": "CONTRAINDICADO",
"requires_confirmation": true,
"confirmation_required_ids": ["drug_allergy-1a2b3c4d5e"],
"total_alerts": 4,
"visible_count": 2,
"suppressed_count": 2,
"suppressed": [
{
"type": "food_alcohol",
"severity": "LEVE",
"id": "food_alcohol-9f8e7d6c5b",
"suppression_reason": "below_min_severity",
"justification": ""
}
]
}
Motivos de supressão (suppression_reason):
| Motivo | Significado |
|---|---|
below_min_severity | Abaixo do nível mínimo de gravidade configurado. |
suppressed_type | Tipo de alerta suprimido pela política (global ou por unidade). |
policy_override | Alerta conhecido suprimido com justification registrada. |
out_of_view | Fora da visão do papel (ex.: drug_disease na visão de farmacêutico). |
Visões por papel (médico × farmacêutico)
Envie o header X-SauBit-Alert-View (ou o query param ?alert_view=) com medico ou
farmaceutico:
curl -X POST https://api.saubit.com.br/api/v1/interactions/check \
-H "X-API-Key: sm_live_..." \
-H "X-SauBit-Alert-View: farmaceutico" \
-H "Content-Type: application/json" \
-d '{ "medications": [ { "name": "ibuprofeno" } ], "patient_record": { "conditions": ["insuficiência renal"] } }'
medico— vê todos os tipos de alerta.farmaceutico— vê os alertas operacionais/de dispensação (alergia, duplicidade, dose máxima, compatibilidade IV, fármaco × lab, ajuste renal/hepático); alertas de raciocínio diagnóstico (ex.:drug_disease) saem da lista comout_of_view.
Alertas críticos são sempre exibidos, independentemente da visão.
Segurança do papel: quando a API key tem um papel vinculado (definido pelo admin —
physician/pharmacist), ele é autoritativo e o headerX-SauBit-Alert-Viewé ignorado (não pode escalar privilégio). O header só vale como preferência de apresentação quando a key não tem papel vinculado. A supressão é apenas de exibição e nunca rebaixa o risco — mas o papel autêntico deve vir da identidade, não de um header livre.
Unidade hospitalar
A unidade é inferida de patient_context.setting (ex.: "UTI", "Pediatria",
"Oncologia") e normalizada para um tag (icu, pediatrics, oncology, emergency,
obstetrics). Uma política pode definir regras específicas por unidade.
Política (por organização / API key)
A política é um objeto JSON configurado por organização (com override por API key). Campos:
| Campo | Tipo | Efeito |
|---|---|---|
enabled | bool | Quando false, vira pass-through (mantém apenas a confirmação crítica). |
min_severity | LEVE·MODERADO·GRAVE·CONTRAINDICADO | Suprime alertas abaixo do limiar. |
confirm_min_severity | idem | Gravidade a partir da qual exige confirmação (padrão CONTRAINDICADO). |
suppressed_types | lista | Tipos de alerta sempre suprimidos (ex.: ["food_alcohol"]). |
suppressed_signatures | lista | Overrides de alertas conhecidos: { "signature": "<id>", "justification": "...", "expires_at"?: "ISO 8601" }. Com expires_at, o override expira e o alerta volta a aparecer. |
unit_rules | objeto | Override por unidade: { "UTI": { "min_severity": "GRAVE" } }. |
role_types | objeto | Tipos visíveis por papel: { "pharmacist": ["drug_allergy", "max_dose"] }. |
Exemplo de política:
{
"enabled": true,
"min_severity": "MODERADO",
"confirm_min_severity": "CONTRAINDICADO",
"suppressed_types": ["food_alcohol"],
"unit_rules": {
"UTI": { "min_severity": "GRAVE" },
"Pediatria": { "suppressed_types": [] }
},
"suppressed_signatures": [
{ "signature": "duplicate_therapy-1a2b3c4d5e", "justification": "Protocolo institucional aprovado pela CCIH" }
]
}
Configuração (rotas administrativas)
A política é configurada por rotas administrativas (JWT de admin, sob /api/v1/admin/*),
com a política da API key tendo precedência sobre a da organização. Como são rotas de
administração, elas são documentadas no Swagger Admin (/docs/admin), separadas das rotas
de hospital — incluindo GET/PUT/DELETE …/organizations/{org_id}/alert-governance e
…/api-keys/{key_id}/alert-governance.
Entradas inválidas (gravidade fora do conjunto, tipo de alerta desconhecido, override sem
justification) retornam 422. Os valores são normalizados (ex.: min_severity em
maiúsculas, unidade convertida para tag).
Propagação: a autenticação por API key é cacheada por ~60s; alterações de política passam a valer em até 60 segundos (o override por key invalida o cache imediatamente).
Métrica: alertas que mudaram a conduta
O indicador-chave da governança não é "quantos alertas foram gerados", e sim quantos mudaram a conduta clínica. Para medir isso, o cliente registra a decisão tomada sobre cada alerta exibido.
Registrar uma decisão
POST /api/v1/interactions/alerts/decision (autenticação por API key, escopo
interactions:check):
curl -X POST https://api.saubit.com.br/api/v1/interactions/alerts/decision \
-H "X-API-Key: sm_live_..." \
-H "Content-Type: application/json" \
-d '{
"analysis_id": "a1b2c3...",
"alert_id": "drug_disease-1a2b3c4d5e",
"decision": "modified",
"changed_conduct": true,
"justification": "Trocado por alternativa segura na gestação"
}'
| Campo | Descrição |
|---|---|
analysis_id | Id da análise (check/recheck) que gerou o alerta. |
alert_id | O id do alerta em clinical_alerts. |
decision | acknowledged (ciente, manteve), overridden (sobrepôs) ou modified (alterou a conduta). |
changed_conduct | true se o alerta efetivamente mudou a prescrição/conduta. |
justification | Obrigatória quando decision = "overridden". |
O servidor valida que a análise pertence à organização e preenche alert_type/severity a
partir da análise armazenada.
Consultar a métrica
A consulta agregada (changed_conduct_rate = fração de decisões em que o alerta mudou a
conduta, além de recortes por tipo/gravidade) é uma rota administrativa e está no
Swagger Admin (/docs/admin): GET …/organizations/{org_id}/alert-metrics. As decisões
registradas acima também alimentam o Dashboard/ROI administrativo.