Guia de Contribuição
Como contribuir para o projeto Sinapse
Obrigado por considerar contribuir para o Sinapse! Este guia ajudará você a entender nosso processo de desenvolvimento e como você pode participar.
Código de Conduta
Ao contribuir, você concorda em respeitar nosso código de conduta:
- Seja respeitoso e inclusivo
- Aceite críticas construtivas
- Foque no que é melhor para a comunidade
- Mostre empatia com outros contribuidores
Como Contribuir
1. Reportando Bugs
Antes de criar um issue:
- Verifique se já não existe um issue similar
- Teste com a versão mais recente
- Colete informações relevantes:
- Versão do Sinapse
- Sistema operacional
- Logs de erro
- Passos para reproduzir
Template para bug report:
### Descrição
Breve descrição do problema
### Passos para Reproduzir
1. Fazer login como admin
2. Acessar /api/v1/usuarios
3. Tentar criar usuário sem email
### Comportamento Esperado
Retornar erro 422 com mensagem clara
### Comportamento Atual
Retorna erro 500 sem detalhes
### Logs[cole os logs relevantes aqui]
### Ambiente
- Sinapse: v1.0.0
- Python: 3.11
- OS: Ubuntu 22.042. Sugerindo Melhorias
Para sugerir uma nova funcionalidade:
- Verifique o roadmap do projeto
- Discuta a ideia em um issue antes de implementar
- Descreva o caso de uso e benefícios
- Considere possíveis impactos
3. Enviando Pull Requests
Setup Inicial
# Fork o repositório no GitHub
# Clone seu fork
git clone [email protected]:seu-usuario/core_sinapse.git
cd core_sinapse
# Adicione o upstream
git remote add upstream [email protected]:InstitutoTodosPelaSaude/core_sinapse.git
# Configure seu ambiente
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txtFluxo de Trabalho
-
Crie uma branch:
# Sincronize com upstream git fetch upstream git checkout main git merge upstream/main # Crie sua branch git checkout -b feature/minha-feature # ou git checkout -b fix/corrigir-bug -
Faça suas alterações:
- Siga os padrões de código
- Adicione testes quando aplicável
- Atualize a documentação
- Mantenha commits atômicos
-
Teste suas alterações:
# Execute os testes pytest # Verifique a formatação black . --check ruff check . # Type checking mypy . -
Commit suas mudanças:
# Commits semânticos git commit -m "feat: adicionar endpoint de busca avançada" git commit -m "fix: corrigir validação de CPF" git commit -m "docs: atualizar README com novos exemplos" git commit -m "test: adicionar testes para módulo de agravos" git commit -m "refactor: simplificar lógica de autenticação" -
Push e crie o PR:
git push origin feature/minha-feature
Padrões de Código
Python Style Guide
Seguimos PEP 8 com algumas extensões:
# Imports organizados com isort
from typing import Optional, List, Dict
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from core.database import get_db
from core.security import get_current_user
from modules.usuarios.schemas import UsuarioSchema
from modules.usuarios.models import UsuarioModel
# Classes com docstrings
class UsuarioService:
"""
Serviço para operações relacionadas a usuários.
Este serviço centraliza toda a lógica de negócio
relacionada ao gerenciamento de usuários.
"""
async def criar_usuario(
self,
*,
db: AsyncSession,
usuario_data: UsuarioSchema,
current_user: UsuarioModel
) -> UsuarioModel:
"""
Cria um novo usuário no sistema.
Args:
db: Sessão assíncrona do banco
usuario_data: Dados do usuário a ser criado
current_user: Usuário autenticado fazendo a requisição
Returns:
UsuarioModel: Usuário criado
Raises:
HTTPException: Se email já existe ou sem permissão
"""
# Implementação...Estrutura de Arquivos
modules/novo_modulo/
├── __init__.py # Exports do módulo
├── module_config.py # Configurações
├── endpoints.py # Rotas FastAPI
├── models.py # Modelos SQLAlchemy
├── schemas.py # Schemas Pydantic
├── async_services.py # Lógica de negócio
├── async_repository.py # Acesso a dados
└── tests/ # Testes do módulo
├── __init__.py
├── test_endpoints.py
└── test_services.pyConvenções de Nomenclatura
- Variáveis e funções: snake_case
- Classes: PascalCase
- Constantes: UPPER_SNAKE_CASE
- Arquivos: snake_case
- URLs: kebab-case
Type Hints
Sempre use type hints:
from typing import Optional, List, Dict, Union
from datetime import datetime
async def processar_dados(
dados: List[Dict[str, Union[str, int]]],
filtro: Optional[str] = None,
limite: int = 100
) -> Dict[str, List[Dict[str, any]]]:
"""Processa dados com filtro opcional."""
resultado: Dict[str, List[Dict[str, any]]] = {
"processados": [],
"erros": []
}
# ...
return resultadoTestes
Estrutura de Testes
# tests/test_usuarios.py
import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession
from main import app
from modules.usuarios.models import UsuarioModel
class TestUsuarios:
"""Testes para o módulo de usuários."""
@pytest.mark.asyncio
async def test_criar_usuario(
self,
client: AsyncClient,
db: AsyncSession,
admin_token: str
):
"""Testa criação de usuário com sucesso."""
# Arrange
usuario_data = {
"email": "[email protected]",
"nome": "Novo Usuario",
"senha": "senha123"
}
# Act
response = await client.post(
"/api/v1/usuarios/",
json=usuario_data,
headers={"Authorization": f"Bearer {admin_token}"}
)
# Assert
assert response.status_code == 201
data = response.json()
assert data["email"] == usuario_data["email"]
assert "senha" not in dataFixtures Comuns
# conftest.py
import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession
@pytest.fixture
async def client():
"""Cliente HTTP para testes."""
async with AsyncClient(app=app, base_url="http://test") as ac:
yield ac
@pytest.fixture
async def admin_user(db: AsyncSession):
"""Usuário admin para testes."""
# Criar e retornar usuário admin
pass
@pytest.fixture
async def admin_token(admin_user):
"""Token JWT de admin."""
# Gerar e retornar token
passDocumentação
Docstrings
Use Google style:
def calcular_estatisticas(
casos: List[AgravoModel],
periodo: str = "mensal"
) -> Dict[str, float]:
"""
Calcula estatísticas de casos de agravos.
Args:
casos: Lista de casos para análise
periodo: Tipo de agrupamento (diario, semanal, mensal)
Returns:
Dict com estatísticas calculadas:
- total: Total de casos
- media: Média por período
- taxa_crescimento: Taxa de crescimento
Raises:
ValueError: Se período não for válido
Example:
>>> casos = await get_casos_dengue()
>>> stats = calcular_estatisticas(casos, "semanal")
>>> print(f"Total: {stats['total']}")
"""Documentação de API
Sempre documente endpoints:
@router.post(
"/",
response_model=UsuarioResponse,
status_code=status.HTTP_201_CREATED,
summary="Criar novo usuário",
description="Cria um novo usuário no sistema. Requer permissão USUARIOS_CRIAR."
)
async def criar_usuario(
usuario: UsuarioCreate,
db: AsyncSession = Depends(get_db),
current_user: UsuarioModel = Depends(requer_permissao("usuarios.criar"))
):
"""
Cria um novo usuário com os dados fornecidos.
- **email**: Email único do usuário
- **nome**: Nome completo
- **senha**: Senha com mínimo 8 caracteres
- **grupos**: Lista de IDs de grupos (opcional)
"""Processo de Review
Checklist do PR
Antes de solicitar review, verifique:
- Código segue os padrões do projeto
- Testes foram adicionados/atualizados
- Documentação foi atualizada
- Sem warnings do linter
- Commits com mensagens claras
- Branch está atualizada com main
- CI está passando
O que esperamos no review
- Código limpo e legível
- Testes adequados
- Documentação clara
- Sem código comentado
- Sem prints de debug
- Segurança considerada
Template de PR
## Descrição
Breve descrição do que foi alterado e por quê.
## Tipo de mudança
- [ ] Bug fix
- [ ] Nova feature
- [ ] Breaking change
- [ ] Documentação
## Como testar
1. Passo 1
2. Passo 2
3. Verificar resultado
## Checklist
- [ ] Testes adicionados
- [ ] Documentação atualizada
- [ ] Código revisado
- [ ] CI passando
## Screenshots (se aplicável)
[Adicione screenshots aqui]
## Issues relacionados
Closes #123Versionamento
Seguimos Semantic Versioning:
- MAJOR: Mudanças incompatíveis na API
- MINOR: Novas funcionalidades compatíveis
- PATCH: Correções de bugs
Exemplos:
1.0.0→2.0.0: Removeu endpoint antigo1.0.0→1.1.0: Adicionou novo endpoint1.0.0→1.0.1: Corrigiu bug de validação
Comunicação
Canais
- GitHub Issues: Bugs e features
- Discussions: Dúvidas e ideias
- Email: [email protected]
Seja claro e específico
✅ Bom: "Endpoint GET /usuarios retorna 500 quando filtro cidade tem acentos"
❌ Ruim: "API não funciona com acentos"
Reconhecimento
Todos os contribuidores são reconhecidos em:
- README.md
- Release notes
- Arquivo CONTRIBUTORS.md
Dúvidas?
Se tiver dúvidas sobre como contribuir:
- Verifique a documentação técnica
- Abra uma discussion
- Entre em contato por email
Obrigado por contribuir para tornar o Sinapse melhor! 🎉