Appearance
Padrões Vue
Adaptação normativa do code-style do Contrasync, consultado em 2026-09-07. Exemplos e dependências específicos de contratos não são requisitos do atpares. Referência técnica: Vue Composition API com TypeScript.
Organização
Usar Vue com Composition API e TypeScript. Cada módulo em src/modules possui services, hooks, components, pages e router. Tipos, constantes e regras puras ficam em src/domain/<modulo>. Componentes genéricos ficam em src/components. Não criar pastas stores, composables ou types por módulo.
Stores Pinia e composables usam hooks/useXxx.ts, sem sufixo Store. Um hook por arquivo e uma função no nível do módulo. Helpers puros vão para domain; helpers visuais podem ficar junto do componente em arquivo próprio. Não esconder complexidade em uma fachada que apenas reexporta um store gigante.
Hooks de módulo não recebem parâmetros. Ações recebem os dados necessários. Componentes genéricos com instâncias independentes podem ter hooks locais parametrizados por refs de props. Evitar ciclos entre hooks. Estado compartilhado tem um dono claro.
Estado e lifecycle
Usar storeToRefs para estado e computed do Pinia; desestruturar ações diretamente. Não acessar store.x no template nem retornar reactive envolvendo refs existentes. Separar estado de edição, calendário, revisão e envio em responsabilidades distintas.
Lifecycle fica em páginas/componentes. Hooks expõem init e reset; consumidores ligam onMounted e onBeforeUnmount. Limpar timers, requisições e watchers criados dinamicamente. Troca de projeto deve limpar estado anterior e descartar respostas antigas para impedir mistura de marcas.
Componentes
Ordem dos blocos: template, script setup lang="ts", style lang="scss" scoped. Componentes são views: regras, chamadas HTTP e tratamento de erros ficam nos hooks e serviços. Props/emits são apropriados para componentes genéricos; componentes internos de módulo consomem seu estado por hooks.
Rotas usam name. Textos da aplicação passam por i18n. Não usar i18n.global.t nos hooks ou componentes. Formulários têm mensagens por campo e limites consistentes com a API. Limites no frontend ajudam UX; somente validação no servidor protege a entrada.
Código e estilos
Sem any, comentários explicativos no código ou funções enormes. Nomes devem explicar a intenção; motivação arquitetural fica na documentação. Inferir retorno das funções Vue. Usar blocos em if, early return, linha vazia após declarações const/let e após blocos if. Evitar if/for aninhados.
Não codificar cores fixas. Usar tokens e suportar estados de foco, erro, carregamento e vazio. SCSS usa BEM. Biblioteca de UI e versão de Tailwind ainda não foram escolhidas: não copiar diretivas específicas do Contrasync como se já existissem no atpares.
Erros remotos devem ser normalizados para mensagens públicas seguras. Não mostrar stack, token ou resposta bruta do provedor. Componentes não contêm try/catch de regras de negócio.
Exemplo de composição
vue
<template>
<button :disabled="loading" @click="loadCampaigns">
{{ t('campaigns.reload') }}
</button>
</template>
<script setup lang="ts">
import { onMounted, onBeforeUnmount } from 'vue'
import { storeToRefs } from 'pinia'
import { useI18n } from 'vue-i18n'
import { useCampaigns } from '@/modules/campaigns/hooks/useCampaigns'
const { t } = useI18n()
const { loading } = storeToRefs(useCampaigns())
const { loadCampaigns, reset } = useCampaigns()
onMounted(loadCampaigns)
onBeforeUnmount(reset)
</script>O exemplo depende do hook a implementar. Não é um componente já existente.
Verificação
Ao implementar: lint, checagem TypeScript e build. Testes devem cobrir troca de projeto durante carregamento, invalidação de aprovação após edição e prevenção de envio duplicado, não apenas replicar getters.