Convenções e testes¶
As convenções abaixo não são preferências de estilo; cada uma sustenta uma propriedade de segurança ou de
operação que o PEART assume como compromisso. Uma mudança que quebra uma delas quebra uma garantia, então o
make check impõe as que dá para impor mecanicamente, e a revisão impõe o resto.
O front-end não tem etapa de build, e não tem innerHTML¶
A interface são páginas estáticas servidas por go:embed, com o Lit vendorizado sob web/vendor/. Não há
Node, nem bundler, nem transpile. Uma contribuição ao front-end é JavaScript puro e templates Lit que rodam
no navegador como foram escritos. Mantenha assim: a ausência de pipeline de build é o que permite a interface
inteira caber num único binário Go e ser auditada lendo os arquivos que de fato são servidos.
A Content-Security-Policy é estrita, sem unsafe-inline e sem unsafe-eval. Isso tem consequência direta em
como você escreve componentes: nada de handlers de evento inline, nada de <style> inline ou injeção de
style= com valores não confiáveis, e nada de innerHTML ou unsafeHTML do Lit no nosso próprio código.
Renderize pelo templating do Lit, que escapa por construção. Um componente que precisa mostrar texto vindo do
usuário liga esse texto como texto, nunca como markup. Esta é a regra de front-end mais importante, porque é
ela que fecha o XSS armazenado na camada de renderização.
Migrações são forward-only¶
As migrações de banco são numeradas e forward-only; não há caminho de down-migration. Uma mudança de schema é um arquivo de migração novo que move o schema adiante e é seguro aplicar a um banco vivo. Isso mantém os upgrades previsíveis e irreversíveis na direção que importa, e significa que você projeta uma migração para estar correta na primeira aplicação em vez de contar com um rollback que não existe.
Erros são explícitos, recursos usam defer¶
Trate erros de forma explícita no ponto em que ocorrem; não os mascare para a função ficar bonita de ler.
Libere todo recurso com defer no ponto de aquisição. Evite estado mutável em nível de pacote. São as
disciplinas comuns de Go, e o código as segue para que o comportamento sob falha seja o comportamento que
você lê direto no código.
Testes são table-driven e paralelos ao código¶
Toda unidade de código tem testes, e lógica complexa usa testes table-driven cobrindo o caminho de sucesso e
o de falha. Os arquivos de teste ficam ao lado do código que testam (foo_test.go para foo.go). Os testes
de navegador dirigem a interface real num Chrome headless e fazem parte da suíte, não de uma camada opcional
à parte; uma mudança num componente não está pronta enquanto o teste de navegador dele não estiver verde. O
make check roda tudo isso.
Formatação e documentação não são opcionais¶
O código é gofmt-limpo e fica dentro de 120 colunas. Todo pacote tem um comentário de pacote acima da
declaração package, e todo identificador exportado tem um comentário de doc que é uma frase completa
começando pelo nome do identificador. Comentários explicam o porquê, em inglês, não o como. O make check
reprova num diff de gofmt, numa linha longa demais, e no gate i18n-check que mantém os catálogos de
mensagens em inglês e português em sincronia, então rode-o antes de enviar qualquer coisa.