Desenvolvimento

Convenções de Código

Padrões, convenções e boas práticas do projeto stCall.

Convenções de Código

Princípios Gerais

  1. Performance primeiro - Toda solução deve considerar impacto na performance
  2. Bun-first - Usar APIs do Bun/Nuxt, evitar APIs específicas do Node.js
  3. DRY - Extrair lógica reutilizável para composables
  4. Responsabilidade única - Um composable, um propósito

Bun-First (Regras Críticas)

// CORRETO
import.meta.client      // Verificar se está no client
import.meta.server      // Verificar se está no server
import.meta.env          // Variáveis de ambiente

// ERRADO - NÃO usar
process.client           // ❌ API Node.js
process.server           // ❌ API Node.js
process.env              // ❌ API Node.js (no contexto Nuxt)
  • Nunca adicionar @types/node salvo absoluta necessidade
  • Preferir ES Modules, nunca CommonJS
  • Usar TypeScript nativo do Bun

Componentes PrimeVue

<!-- CORRETO - PascalCase sem prefixo -->
<Button label="Salvar" severity="success" />
<DataTable :value="items">
  <Column field="name" header="Nome" />
</DataTable>
<Dialog v-model:visible="show" modal>

<!-- ERRADO - NÃO usar p-prefix -->
<p-button />     <!-- ❌ -->
<p-data-table /> <!-- ❌ -->

Barrel Exports

USAR em:

  • Stores (stores/index.ts) - Stores são usadas juntas frequentemente
  • Types (types/index.ts) - Tipos não têm custo de runtime
// stores/index.ts
export { useCallStore } from './callStore'
export { useAuthStore } from './authStore'

// Uso:
import { useCallStore, useAuthStore } from '~/stores'

NÃO USAR em:

  • Composables - Auto-importados pelo Nuxt (cria duplicatas)
  • Components - Auto-importados pelo Nuxt
  • Pages - File-based routing
Nunca crie composables/index.ts. O Nuxt auto-importa todos os composables e um barrel export causaria duplicação de imports.

Composables

Organização

Composables são organizados por domínio em subdiretórios:

composables/
├── agent/      # Agentes
├── audio/      # Áudio
├── calls/      # Chamadas
├── webrtc/     # WebRTC
├── ws/         # WebSocket
├── storage/    # Persistência
└── utils/      # Utilitários

Nomeação

  • Prefixo use (ex: useCallDuration)
  • Nome descritivo do propósito
  • Um arquivo por composable

Documentação

Usar JSDoc com exemplos:

/**
 * useCallDuration - Timer automático de duração de chamada
 *
 * @param getCall - Função que retorna a chamada ativa
 * @returns { callDuration, startTimer, stopTimer }
 *
 * @example
 * const { callDuration } = useCallDuration(() => activeCall.value)
 */

TypeScript

Modo Estrito

TypeScript está em modo estrito. Sempre usar tipos explícitos.

Tipos Compartilhados

Definir em types/ com export via types/index.ts:

// types/call.ts
export interface Call {
  id: string
  number: string
  status: CallStatus
  direction: CallDirection
  // ...
}

// types/index.ts
export type { Call, CallStatus, CallDirection } from './call'

Import de Tipos

Usar import type para importações de tipo:

import type { Call, Agent } from '~/types'

Idioma

  • Interface: Português (PT-BR)
  • Código: Inglês (nomes de variáveis, funções, tipos)
  • Sem i18n no MVP - textos hardcoded em português
  • Mensagens de toast: Português

CSS e Styling

  • Usar Tailwind CSS para styling
  • Usar PrimeVue components sempre que possível
  • Evitar CSS customizado exceto quando necessário
  • Modo escuro: classe .stcall-dark-mode
  • Cor primária: Laranja (configurada no tema)

Estado Global

  • Pinia para estado global
  • Stores definidas com defineStore
  • Getters para dados derivados
  • Actions para operações assíncronas
  • Persistência via localStorage quando necessário

Erros e Notificações

Usar o padrão useCommandExecutor para operações com feedback:

const { execute } = useCommandExecutor()

await execute({
  action: async () => { /* operação */ },
  successMessage: { title: 'Sucesso', detail: 'Operação OK' },
  errorMessage: 'Falha na operação',
  showSuccessToast: true,
  showErrorToast: true,
})
Copyright © 2026