Plugin system para mappings¶
Diátaxis: explanation. RFC base para
v1.2. Para o como usar, vejadocs/reference/cli.mdseçãomappings list.
Problema¶
Cada secretaria de saúde brasileira customiza seu e-SUS, SISREG e
SEI. O Anotae já entrega mappings built-in (vocabularies/mappings/)
para o piloto APS/DF. Conforme adoção cresce:
- UBSs em outros estados querem mappings próprios sem PR no repo principal (workflow lento para customização local).
- Mantenedores querem que mappings comunitários convivam com os built-in sem sobrescrever acidentalmente.
- Multi-tenant (mais de um SEI no mesmo PC, ex.: SEI/DF + SEI/SES-SP) precisa de prioridade explícita.
Modelo¶
Três fontes de mappings, em ordem de prioridade crescente:
BUILTIN (vocabularies/mappings/) ← release-signed
↓ pode ser sobrescrito por
USER (~/.anotae/mappings/) ← opt-in do usuário
↓ pode ser sobrescrito por
CUSTOM (ANOTAE_MAPPING_PATHS env var) ← multi-tenant / dev
A unidade de identidade é o campo id no JSON. Conflitos são
resolvidos elegendo a fonte de maior prioridade. O id perdedor
fica registrado em DiscoveryReport.overridden para auditoria.
Decisões¶
Plugins são apenas dados¶
Os mappings são JSON — sem código executável, sem eval. A
extensão de navegador interpreta target_selectors (CSS / id / name /
aria-label / label); a engine Python só carrega e valida.
Trade-off: - Pro: zero risco de execução arbitrária via mapping malicioso. - Contra: limita expressividade. Para transforms complexas (ex.: formatar data antes de injetar) precisamos estender o JSON com enum de transforms — não com expressões livres.
Validação obrigatória¶
Mappings inválidos são pulados com warning, não derrubam o app.
DiscoveryReport.skipped lista cada arquivo + motivo. CLI
anotae mappings list mostra os pulados ao final.
Sem hot-reload por agora¶
Mudanças em ~/.anotae/mappings/ exigem restart do app. Hot-reload
é planejado para v1.2+ se demanda surgir — adiciona complexidade
(invalidação de caches, sinalização para extensão) sem ganho
imediato no piloto.
Sem versionamento semântico forçado¶
O JSON tem version (string livre). Não há check de compatibilidade
entre versões — confia no autor do mapping para gerenciar quebras.
Vamos formalizar quando alguma operação destrutiva entre versões
aparecer (esperamos que nunca: mappings são aditivos por natureza).
Quando promover USER → BUILTIN¶
Critérios para um mapping comunitário virar built-in:
- Cobertura clara:
target_system+target_version+ (se aplicável)target_instancebem definidos. - Validado em pelo menos 2 UBSs distintas (relato + screenshot sem PII).
- Mantenedor identificado dispostos a manter o mapping em release futuras.
- PR aprovado + entrada em
THIRD_PARTY_NOTICES.mdse o mapping reusou trabalho existente (ex.: SEI Pro AGPL-3.0).
Como criar um mapping novo¶
Para uso pessoal/local (sem PR):
mkdir -p ~/.anotae/mappings
cp vocabularies/mappings/sei-relatorio-ses-df.json \
~/.anotae/mappings/sei-relatorio-meu-orgao.json
# editar id, name, target_instance e selectors específicos
anotae mappings list # confere que carregou como source=user
Para teste em dev sem alterar ~/.anotae/mappings/:
export ANOTAE_MAPPING_PATHS=/tmp/mappings-dev
mkdir -p /tmp/mappings-dev
# colocar JSONs lá
anotae mappings list # source=custom
Quando reabrir esta decisão¶
- Demanda por mappings com lógica condicional → estender JSON com enum de transforms ou avaliar embed de Lua/Starlark sandbox.
- Distribuição via package manager (npm, pip de mapping bundles)
→ adicionar
entry_pointsem vez de pastas só de filesystem. - Hot-reload vira requisito → adicionar watchdog em
~/.anotae/mappings/+ sinal Qt para recarregar combo de Integrações.