refactor(ux): garantir agnosticismo polimorfico e exemplos neutros nos artefatos de UX

This commit is contained in:
Luiz Silva 2026-10-26 20:25:21 -03:00
parent b540fd97c0
commit 790b56e614
21 changed files with 259 additions and 254 deletions

View file

@ -1,7 +1,7 @@
---
type: rule
name: mensagens-usuario
description: Toda mensagem visível ao usuário final deve ser escrita em linguagem do domínio, sem termos técnicos de TI, seguindo as boas práticas de UX Writing do Material Design 3
description: Toda mensagem visível ao usuário final deve ser escrita em linguagem do domínio do módulo (definido em memorias-ia/modulo.yml), sem termos técnicos de TI, seguindo as boas práticas de UX Writing do Material Design 3
scope: global
trigger: glob
globs: "**/*.vue, **/*.ts, **/*.tsx"
@ -12,9 +12,9 @@ updatedAt: "2026-10-26"
## Contexto
O usuário final dos módulos SaaS é profissional de **engenharia, ciência, administração pública ou gestão ambiental**. Ele entende de legislação, processos técnicos e operação — mas **não tem obrigação de entender tecnologia**.
O usuário final dos módulos do ecossistema é especialista no **domínio de negócio do módulo** (cujo escopo, propósito e público-alvo devem ser consultados obrigatoriamente em `memorias-ia/modulo.yml` nos campos `modulo-descricao` e `modulo-tipo`) — mas **não tem obrigação de entender engenharia de software ou banco de dados**.
Toda mensagem e microcopy visível na interface — títulos de telas, cabeçalhos de seções, modais, painéis laterais, erros, validações, confirmações, tooltips, estados vazios e botões — deve unir a **linguagem do domínio do módulo** às **boas práticas de UX Writing do Material Design 3** (`https://m3.material.io/foundations/writing/best-practices`).
Toda mensagem e microcopy visível na interface — títulos de telas, cabeçalhos de seções, modais, painéis laterais, erros, validações, confirmações, tooltips, estados vazios e botões — deve unir a **linguagem do domínio do módulo ativo** às **boas práticas de UX Writing do Material Design 3** (`https://m3.material.io/foundations/writing/best-practices`).
---
@ -30,12 +30,12 @@ Usar voz ativa, tom neutro (sem culpar o usuário e sem pontos de exclamação `
"Erro de validação"
"Formato inválido"
"Payload inválido"
"Informe a Área do Empreendimento"
"Informe a Razão Social da Organização"
// ✅ CORRETO — linguagem do domínio + Sentence case (M3)
"Informe a área do empreendimento (em hectares)"
"Selecione o tipo de licença: LP, LI ou LO"
"A data da vistoria deve ser anterior à data de hoje"
"Informe a razão social da organização"
"Selecione a categoria da solicitação"
"A data de conclusão deve ser posterior à data de início"
"Informe o CNPJ no formato 00.000.000/0000-00"
```
@ -57,17 +57,17 @@ Explicar o que ocorreu de forma direta e como o usuário pode prosseguir, sem ex
### 3. Estados vazios (*empty states*) devem explicar o contexto e orientar a ação
Quando uma lista, tabela ou painel está vazio, o texto principal não usa ponto final e o texto de apoio orienta o próximo passo:
Quando uma lista, tabela ou painel está vazio, o título não usa ponto final e o texto de apoio orienta o próximo passo:
```typescript
// ❌ ERRADO — genérico e sem saída
"Nenhum registro encontrado."
"Lista vazia"
// ✅ CORRETO — explica o domínio e orienta
// Título (sem ponto final): "Nenhuma condicionante cadastrada"
// Apoio: "Para iniciar o controle de prazos, adicione a primeira condicionante desta licença."
// Botão CTA: "Adicionar condicionante"
// ✅ CORRETO — explica o contexto do domínio e orienta
// Título (sem ponto final): "Nenhuma etapa cadastrada neste cronograma"
// Apoio: "Para iniciar o acompanhamento de prazos, adicione a primeira etapa."
// Botão CTA: "Adicionar etapa"
```
### 4. Diálogos de confirmação devem explicar a consequência e usar botões específicos (M3)
@ -88,15 +88,15 @@ Todo modal de confirmação/decisão crítica (`v-dialog`) deve obedecer à **An
// ✅ CORRETO — Anatomia M3 (Pergunta específica + Consequência + Verbo no botão)
{
titulo: "Excluir condicionante?",
corpo: "O prazo de cumprimento e os documentos vinculados serão removidos permanentemente.",
botoes: ["Cancelar", "Excluir condicionante"]
titulo: "Excluir etapa do cronograma?",
corpo: "Os prazos e os documentos vinculados a esta etapa serão removidos permanentemente.",
botoes: ["Cancelar", "Excluir etapa"]
}
{
titulo: "Arquivar licença?",
corpo: "Esta licença sairá das listagens ativas, mas poderá ser consultada no histórico.",
botoes: ["Cancelar", "Arquivar licença"]
titulo: "Arquivar solicitação?",
corpo: "Esta solicitação sairá das listagens ativas, mas poderá ser consultada no histórico.",
botoes: ["Cancelar", "Arquivar solicitação"]
}
```
@ -108,30 +108,30 @@ Nunca finalizar `label` com dois-pontos (`:`) nem usar ponto final (`.`) em `lab
// ❌ ERRADO — genérico, com dois-pontos ou Title Case em todas as palavras
label: "Nome:"
placeholder: "Digite aqui."
label: "Razão Social Do Empreendedor:"
label: "Razão Social Do Solicitante:"
// ✅ CORRETO — específico do domínio, Sentence case e sem pontuação final
label: "Razão social do empreendedor"
placeholder: "Ex.: Mineração Vale Verde Ltda."
label: "Razão social do solicitante"
placeholder: "Ex.: Organização Vale Verde Ltda."
label: "Área total do empreendimento (ha)"
placeholder: "Ex.: 150,5"
label: "Valor estimado do contrato (R$)"
placeholder: "Ex.: 15.000,00"
```
### 6. Schemas Zod devem ter mensagens de domínio em *Sentence case*
```typescript
// ❌ ERRADO — mensagens padrão do Zod em inglês ou técnicas
const zEmpreendimento = z.object({
const zCadastro = z.object({
nome: z.string().min(1),
area: z.number().positive(),
valor: z.number().positive(),
})
// ✅ CORRETO — mensagens customizadas em linguagem do domínio
const zEmpreendimento = z.object({
nome: z.string().min(1, "Informe a razão social do empreendimento"),
area: z.number({ invalid_type_error: "Informe um valor numérico para a área" })
.positive("A área deve ser maior que zero"),
const zCadastro = z.object({
nome: z.string().min(1, "Informe a razão social da organização"),
valor: z.number({ invalid_type_error: "Informe um valor numérico válido" })
.positive("O valor deve ser maior que zero"),
cnpj: z.string().regex(/^\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}$/,
"CNPJ inválido. Use o formato 00.000.000/0000-00"),
})
@ -144,13 +144,13 @@ const zEmpreendimento = z.object({
Toda escrita em componentes Vue (`*-front`) deve aplicar os 7 princípios do guia `m3.material.io/foundations/writing/best-practices`:
1. **Capitalização estilo de frase (*Sentence case*):**
- Usar maiúscula **apenas na primeira letra da primeira palavra** e em **nomes próprios ou siglas oficiais** (`CNPJ`, `CPF`, `IBAMA`, `LP`, `LI`, `LO`, `ART`, `MTR`, `UF`).
- Aplica-se a: títulos de páginas, cabeçalhos de cards/seções, títulos de modais e painéis laterais, labels de inputs, abas (`v-tab`), itens de menu e botões (`"Nova licença"`, `"Salvar alterações"`, `"Dados do empreendimento"`).
- **Proibido** usar *Title Case* anglófono (`"Salvar Alterações"`, `"Dados Do Empreendimento"`) ou `ALL CAPS` em botões e títulos.
- Usar maiúscula **apenas na primeira letra da primeira palavra** e em **nomes próprios ou siglas oficiais** (`CNPJ`, `CPF`, `CEP`, `UF`, `PDF`, `API`).
- Aplica-se a: títulos de páginas, cabeçalhos de cards/seções, títulos de modais e painéis laterais, labels de inputs, abas (`v-tab`), itens de menu e botões (`"Nova solicitação"`, `"Salvar alterações"`, `"Dados do responsável"`).
- **Proibido** usar *Title Case* anglófono (`"Salvar Alterações"`, `"Dados Do Responsável"`) ou `ALL CAPS` em botões e títulos.
2. **Começar pelo objetivo (*Begin with the objective*):**
- Quando uma frase orientativa descreve uma meta e a ação necessária para atingi-la, **iniciar a frase pelo objetivo** para facilitar o escaneamento rápido:
- ✅ `"Para emitir a licença, anexe o parecer técnico conclusivo"`
- ❌ `"Anexe o parecer técnico conclusivo para emitir a licença"`
- ✅ `"Para concluir a solicitação, anexe o documento comprobatório"`
- ❌ `"Anexe o documento comprobatório para concluir a solicitação"`
3. **Pontuação enxuta para escaneabilidade (*Skip unnecessary punctuation*):**
- **Omitir ponto final (`.`)** em: rótulos (`label`), botões, títulos e subtítulos, cabeçalhos de seção, tooltips curtos de 1 frase, toasts/snackbars de 1 frase e itens de lista (*bullet points*) de frase única.
- **Proibir dois-pontos (`:`)** ao final de títulos, cabeçalhos de seção/lista e labels de campos (`<h3>Documentos exigidos</h3>` e nunca `<h3>Documentos exigidos:</h3>`).
@ -160,9 +160,9 @@ Toda escrita em componentes Vue (`*-front`) deve aplicar os 7 princípios do gui
- **Proibido** usar pontos de exclamação (`!`) ou palavras alarmistas (`"Atenção!"`, `"Erro fatal!"`, `"Cuidado!"`) em mensagens de erro ou aviso.
5. **Consistência de pessoa verbal (2ª pessoa):**
- Dirigir-se diretamente ao usuário em 2ª pessoa (`"você"`, `"seu/sua"`).
- **Nunca misturar** 1ª pessoa (`"Meus processos"`) e 2ª pessoa (`"Gerencie seus processos"`) na mesma tela ou fluxo.
- **Nunca misturar** 1ª pessoa (`"Minhas solicitações"`) e 2ª pessoa (`"Gerencie suas solicitações"`) na mesma tela ou fluxo.
6. **Algarismos para números e zero abreviações truncadas (*Use numerals & Avoid abbreviations*):**
- Escrever números, limites e contadores **sempre como algarismos** (`"3 condicionantes pendentes"`, `"Até 10 MB"`, `"Há 2 dias"`), nunca por extenso (`"três condicionantes"`).
- Escrever números, limites e contadores **sempre como algarismos** (`"3 pendências encontradas"`, `"Até 10 MB"`, `"Há 2 dias"`), nunca por extenso (`"três pendências"`).
- **Proibido** usar abreviações truncadas na interface (`"Qtd."`, `"Obs."`, `"Cad."`, `"End."`, `"Dt."`, `"Máx."`, `"Mín."`, `"Tel."`). Escrever a palavra por extenso (`"Quantidade"`, `"Observações"`, `"Cadastro"`, `"Endereço"`, `"Data"`, `"Máximo"`).
7. **Acessibilidade textual (*Alt text & Anti-truncamento cego*):**
- Textos alternativos (`alt`) devem ser concisos (até **125 caracteres**) e descrever a função/conteúdo sem iniciar por `"Imagem de..."` ou `"Ícone de..."`. Imagens decorativas devem usar `alt=""`.
@ -172,11 +172,12 @@ Toda escrita em componentes Vue (`*-front`) deve aplicar os 7 princípios do gui
## Impacto
Sem esta regra, o agente gera interfaces com textos prolixos, capitalização inconsistente (*Title Case* misturado com *Sentence case*), botões de confirmação ambíguos (`Sim/OK`), abreviações amadoras (`Qtd.`, `Obs.`) e mensagens técnicas que confundem o usuário final.
Sem esta regra, o agente gera interfaces com textos prolixos, capitalização inconsistente (*Title Case* misturado com *Sentence case*), botões de confirmação ambíguos (`Sim/OK`), abreviações amadoras (`Qtd.`, `Obs.`) e mensagens técnicas ou de outro domínio que confundem o usuário final.
## Referências
- Material Design 3 — Writing Best Practices: `https://m3.material.io/foundations/writing/best-practices`
- Rule: `global/rules/identidade-modulo` (`memorias-ia/modulo.yml`)
- Rule: `global/rules/zod-validacao-padrao` (schemas com mensagens customizadas)
- Rule: `global/rules/refactoring-ui-hierarquia-despoluicao` (hierarquia visual e despoluição)
- Skill: `skills/ux-fluxo-funcional/SKILL.md` (jornada e organização de telas, modais e painéis)