Pular para o conteúdo principal

Guia de Contribuição

Obrigado pelo interesse em contribuir para o APAH Assistant! Este guia explica como participar no desenvolvimento do projeto.

Código de Conduta

Ao contribuir, concorda em manter um ambiente respeitoso e inclusivo para todos os participantes.

Pré-requisitos

  • Node.js 20+
  • pnpm 9+
  • Docker
  • Git
  • VS Code (recomendado)

Setup do Ambiente de Desenvolvimento

1. Fork e Clone

# Fork via GitHub UI, depois:
git clone https://github.com/SEU-USERNAME/apah-assistant.git
cd apah-assistant

2. Configurar Upstream

git remote add upstream https://github.com/Visual-Thinking/apah-assistant.git

3. Instalar Dependências

pnpm install

4. Configurar Ambiente

cp .env.example .env
# Editar .env com as suas configurações

5. Iniciar Base de Dados

docker-compose up -d
pnpm db:migrate

6. Iniciar Desenvolvimento

pnpm dev

Workflow de Contribuição

1. Criar Branch

# Atualizar main
git checkout main
git pull upstream main

# Criar branch de feature
git checkout -b feature/nome-da-feature

Convenção de Nomes de Branches

TipoFormatoExemplo
Featurefeature/descricaofeature/chat-history
Bug fixfix/descricaofix/login-error
Docsdocs/descricaodocs/api-reference
Refactorrefactor/descricaorefactor/auth-service

2. Desenvolver

Faça as suas alterações seguindo as guidelines abaixo.

3. Testar

# Verificar tipos
pnpm typecheck

# Verificar linting
pnpm check

4. Commit

git add .
git commit -m "feat: descrição da alteração"

Convenção de Commits

Usamos Conventional Commits:

TipoDescrição
featNova funcionalidade
fixCorreção de bug
docsDocumentação
styleFormatação (sem alteração de código)
refactorRefatoração
testTestes
choreManutenção

Exemplos:

feat: adicionar histórico de chat
fix: corrigir erro de autenticação no login
docs: atualizar guia de instalação
refactor: extrair lógica de embeddings

5. Push

git push origin feature/nome-da-feature

6. Pull Request

  1. Abra um PR no GitHub
  2. Preencha o template
  3. Aguarde review

Guidelines de Código

TypeScript

// ✅ Bom: Tipos explícitos
interface User {
id: string;
name: string;
email: string;
}

function getUser(id: string): Promise<User | null> {
// ...
}

// ❌ Evitar: any
function getUser(id: any): any {
// ...
}

React Components

// ✅ Bom: Componentes funcionais com tipos
interface ButtonProps {
children: React.ReactNode;
onClick: () => void;
variant?: "primary" | "secondary";
}

export function Button({ children, onClick, variant = "primary" }: ButtonProps) {
return (
<button onClick={onClick} className={cn(buttonVariants({ variant }))}>
{children}
</button>
);
}

Imports

// ✅ Organização de imports
// 1. Bibliotecas externas
import { useState } from "react";
import { z } from "zod";

// 2. Imports internos (alias @/)
import { Button } from "@/components/ui/button";
import { api } from "@/lib/trpc/client";

// 3. Imports relativos
import { UserCard } from "./user-card";

Naming

TipoConvençãoExemplo
ComponentesPascalCaseUserProfile
FunçõescamelCasegetUserById
VariáveiscamelCaseisLoading
ConstantesUPPER_SNAKEMAX_FILE_SIZE
Ficheiroskebab-caseuser-profile.tsx
Tipos/InterfacesPascalCaseUserProfile

shadcn/ui

Usar componentes do shadcn/ui sempre que possível:

// ✅ Usar shadcn/ui
import { Button } from "@/components/ui/button";
import { Dialog } from "@/components/ui/dialog";

// ❌ Evitar componentes custom quando shadcn tem equivalente

Estrutura de Ficheiros

src/app/[lang]/(app)/feature/
├── page.tsx # Página principal
├── layout.tsx # Layout (se necessário)
├── _components/ # Componentes específicos
│ ├── feature-list.tsx
│ └── feature-form.tsx
├── actions.ts # Server Actions
└── types.ts # Tipos específicos

Documentação

  • Documente funções públicas com JSDoc
  • Atualize a documentação quando alterar APIs
  • Inclua exemplos de uso
/**
* Pesquisa documentos por similaridade semântica.
*
* @param query - Texto de pesquisa
* @param limit - Número máximo de resultados (default: 5)
* @returns Array de documentos ordenados por relevância
*
* @example
* const docs = await searchDocuments("sintomas HAP", 10);
*/
export async function searchDocuments(
query: string,
limit = 5
): Promise<Document[]> {
// ...
}

Review Process

O que procuramos

  • ✅ Código limpo e legível
  • ✅ Tipos TypeScript corretos
  • ✅ Sem erros de linting
  • ✅ Segue as convenções do projeto
  • ✅ Documentação atualizada
  • ✅ Sem breaking changes não anunciados

Responder a Feedback

  • Seja receptivo a sugestões
  • Explique decisões técnicas quando necessário
  • Faça alterações solicitadas ou discuta alternativas

Reportar Issues

Bugs

Inclua:

  • Descrição do problema
  • Passos para reproduzir
  • Comportamento esperado vs atual
  • Screenshots (se aplicável)
  • Ambiente (OS, browser, versões)

Feature Requests

Inclua:

  • Descrição da funcionalidade
  • Caso de uso
  • Possível implementação (opcional)

Recursos

Contacto

Para questões sobre contribuição:

  • Abra uma Issue no GitHub
  • Discussões no repositório

Obrigado por contribuir! 🎉