# Como contribuir

> Contribua com o Nodaro no GitHub: prepare o ambiente de desenvolvimento, crie a branch a partir de dev, rode os testes, inclua um changeset e assine o CLA.

Source: https://nodaro.ai/pt-BR/docs/self-hosting/contributing

**Contribuir** com o Nodaro significa enviar código para o repositório público, [github.com/nodaroai/app.nodaro.ai](https://github.com/nodaroai/app.nodaro.ai), como um pull request. O Nodaro tem o código-fonte disponível (source-available) sob a Nodaro Sustainable Use License. Esta página trata do ambiente de desenvolvimento, das branches, dos pull requests, dos testes e do contrato de colaborador.

Para rodar o Nodaro no seu próprio servidor, comece pelo [Início rápido](https://nodaro.ai/docs/self-hosting/quickstart). Para criar algo sobre a API, veja o [SDK](https://nodaro.ai/docs/developers/sdk).

## O repositório
O repositório é um monorepo com npm workspaces:

| Pasta | O que fica ali |
| --- | --- |
| `backend/` | A API Fastify, os workers do BullMQ e o orquestrador. Node.js 22, TypeScript. |
| `frontend/` | O app Vite: o editor, o executor de apps e o painel de administração. React 19, React Router 7, React Flow. |
| `packages/` | `@nodaro/shared`, a lógica pura compartilhada por toda a stack; `@nodaro/sdk`, o cliente REST tipado; `@nodaro/cli`; `@nodaro/prompts`, a camada de prompts; e as composições de vídeo do Remotion. |
| `supabase/` | O esquema do banco de dados, como migrações SQL que só avançam. |
| `docs/` | A documentação do repositório, incluindo notas de design que explicam os motivos por trás dos recursos principais. |
| `scripts/` | Utilitários do repositório, como o gerador do grafo da arquitetura e as auditorias. |
| `.changeset/` | Os incrementos de versão pendentes dos pacotes publicados. |

As regras da casa estão no `CLAUDE.md`, na raiz do repositório: os padrões de código, o checklist para adicionar um provedor de modelos e o checklist para adicionar um nó. Leia esse arquivo antes de um pull request que não seja trivial. A página [Arquitetura](https://nodaro.ai/docs/self-hosting/architecture) explica como as partes se encaixam.

## Preparar o ambiente de desenvolvimento
Você precisa do Node.js 22 ou mais recente, com o npm.

### Clonar e instalar
```bash
git clone https://github.com/nodaroai/app.nodaro.ai
cd app.nodaro.ai
npm install        # installs every workspace
```

### Configurar o ambiente
```bash
cp .env.example .env
```

Defina pelo menos `SUPABASE_URL`, `SUPABASE_SERVICE_ROLE_KEY`, `SUPABASE_ANON_KEY`, `INTERNAL_ORCHESTRATOR_SECRET` e uma chave de provedor, como `KIE_API_KEY`, `REPLICATE_API_TOKEN` ou `ANTHROPIC_API_KEY`. Gere os segredos:

```bash
echo "INTERNAL_ORCHESTRATOR_SECRET=$(openssl rand -hex 32)" >> .env
echo "NODARO_ENCRYPTION_KEY=$(openssl rand -hex 32)" >> .env
```

O banco de dados mais fácil é um projeto gratuito no supabase.com. Uma stack totalmente local com a CLI do Supabase, `supabase start`, também funciona, mas exige mais configuração. As execuções de workflows também precisam do Redis, em `REDIS_URL`, cujo padrão é `redis://localhost:6379`. O `.env.example` lista todas as variáveis aceitas, e a página [Configuração](https://nodaro.ai/docs/self-hosting/configuration) as explica.

### Compilar o pacote compartilhado uma vez
O frontend lê o `@nodaro/shared` a partir da saída da build dele, então compile-o antes da primeira inicialização. Depois disso, o script de desenvolvimento do próprio pacote o recompila quando você edita o código compartilhado.

```bash
npm -w @nodaro/shared run build
```

### Iniciar os servidores de desenvolvimento
Em dois terminais:

```bash
# Terminal 1: the API on port 9000
cd backend
npm run dev

# Terminal 2: the frontend on port 3000, which forwards /v1/* to port 9000
cd frontend
npm run dev
```

## Padrões de código
As regras mais importantes do `CLAUDE.md`:

- **Tamanho dos arquivos.** De 200 a 400 linhas é o normal, e 800 é o limite máximo. Divida um arquivo que cresça além disso.
- **Nada de `console.log` em código de produção.** Use os padrões de logger existentes.
- **Conventional commits:** `feat:`, `fix:`, `refactor:`, `docs:`, `chore:`, `test:`, com uma linha de assunto específica.
- **Verifique os tipos antes de cada commit**, com `npx tsc --noEmit` em `backend/` e em `frontend/`. A CI bloqueia os pull requests que não passam na verificação de tipos.
- **Plugins do Fastify, não routers do Express.** Todo arquivo de rota exporta uma função assíncrona que recebe a instância do Fastify.
- **Todo endpoint da API tem um schema Zod**, sem exceções. O schema valida a requisição e também gera o documento OpenAPI.
- **Estado do frontend:** React Query para o estado do servidor, Zustand para o estado da interface e React Flow para o estado do canvas. Não os misture.
- **Nunca faça mutação de objetos ou arrays.** Sempre crie cópias novas: tanto o Zustand quanto o React Flow dependem da igualdade por referência.

## Branches e pull requests
- O repositório tem duas branches permanentes: `dev`, para staging, e `main`, para produção.
- Faça um fork do repositório, **crie a branch a partir de `dev`** e abra o pull request para `dev`. Nunca crie uma branch a partir de `main` nem faça commits diretamente nela.
- Dê à branch um nome pelo tipo dela: `feat/`, `fix/`, `refactor/`, `docs/`, `chore/` ou `test/`, por exemplo `feat/whisper-tts-node`.
- As mudanças mescladas rodam primeiro na instância de staging, `next.nodaro.ai`. Depois de um período de observação de cerca de 24 horas, um mantenedor promove a `dev` para a `main`.

No seu pull request:

- Vincule a issue do GitHub a que ele se refere.
- Adicione capturas de tela ou GIFs para mudanças na interface.
- Siga o checklist de nós do `CLAUDE.md` quando adicionar ou alterar um nó.
- Adicione um changeset quando alterar um pacote publicado. Veja [Changesets](#changesets).

## Testes
Cada workspace tem a própria suíte Vitest. Rode tudo a partir da raiz do repositório, ou um workspace de cada vez:

```bash
npm test                       # every workspace's test script

npm -w @nodaro/shared test     # pure-logic unit tests
npm -w @nodaro/sdk test        # SDK contract tests against a mocked API
cd backend && npm test         # route and service tests
cd frontend && npm test        # component and hook tests
```

O que testar:

- **Rotas da API** — o caminho principal, mais os casos extremos que o seu schema lista. Faça mock do Supabase e dos provedores de IA: um teste unitário nunca chama a API real de um provedor. A maioria dos testes existentes tem uma configuração que você pode copiar.
- **Componentes do frontend** — testes de fumaça (smoke tests) com o React Testing Library. Coloque a lógica pesada em hooks ou helpers, onde ela pode ser testada isoladamente, e não teste os detalhes internos do React Flow nem os stores do Zustand.
- **O pacote compartilhado** — testes unitários de funções puras. As exportações dele precisam continuar serializáveis entre o frontend e o backend.

A CI roda `tsc --noEmit`, o Vitest e uma pequena etapa de lint. Se um teste falhar localmente, mas passar na CI, ou o contrário, abra uma issue com os passos para reproduzir o problema.

### Verificações da saída do ffmpeg
Os testes unitários comuns verificam os argumentos passados ao ffmpeg, não o que o ffmpeg renderiza. Uma suíte de caracterização separada renderiza arquivos de teste (fixtures) por todas as operações que usam o ffmpeg. Depois, ela compara propriedades medidas da saída decodificada com valores de referência registrados no repositório: energia, espectro, decaimento, duração e brilho por quadro.

A suíte fica fora do `npm test`: os números dela só valem para a build exata do ffmpeg fixada na imagem de produção. Rode-a dentro dessa imagem:

```bash
backend/scripts/characterize-in-image.sh check   # compare with the reference values
backend/scripts/characterize-in-image.sh bless   # rewrite the reference values, on purpose only
cd backend && npm run characterize:report -- --against ffmpeg-X.json
```

Se você alterar uma operação que usa o ffmpeg, rode `check` antes de abrir o pull request. A CI também o roda. Se a sua mudança tiver a intenção de alterar a saída renderizada, faça o bless dentro da imagem e faça commit dos novos valores de referência, com uma explicação de cada medida que mudou. Nunca edite os valores de referência manualmente, e nunca faça o bless com um ffmpeg local: a proteção de versão da suíte o rejeita.

## Adicionar um nó ou um provedor de modelos
Adicionar um nó mexe em muitos arquivos: uma rota da API, um componente do frontend, o executor e vários registros. Esquecer um deles dá resultados confusos, como um nó que não aparece em um dos menus de nós ou um botão **Executar** que não faz nada. Siga o checklist **New Node Registration** do `CLAUDE.md`, passo a passo.

Adicionar um modelo a um nó existente é um trabalho mais curto, com o próprio checklist **Provider Enum Sync** no `CLAUDE.md`. A etapa mais esquecida é o schema da rota da API: sem ele, o editor oferece uma opção que a API rejeita com `400`.

## Changesets
Três pacotes são publicados no npm: `@nodaro/shared`, `@nodaro/sdk` e `@nodaro/cli`. As versões usam o Changesets e são automatizadas. Quando a sua mudança afeta um deles:

```bash
npx changeset
```

Escolha os pacotes, o tipo de incremento (patch, minor ou major) e um resumo de uma linha. Faça commit do arquivo que ele grava em `.changeset/` junto com o seu pull request. A verificação **Changeset Guard** reprova os pull requests que alteram um pacote publicado sem um changeset. Para uma mudança que não precisa de nota de versão, use `npx changeset --empty`.

Todo o resto é automático. Na `dev`, um pull request **Version Packages** reúne os changesets pendentes. Quando a `dev` é promovida para a `main`, o workflow de release publica as novas versões no npm, cria as tags delas, cria as releases no GitHub e recompila os binários independentes da CLI. Os workspaces `backend`, `frontend` e Remotion nunca são publicados e não precisam de changeset.

## Código de conduta
Seja gentil, trate todos com respeito e presuma boa-fé. O projeto segue o Contributor Covenant 2.1, em [CODE_OF_CONDUCT.md](https://github.com/nodaroai/app.nodaro.ai/blob/main/CODE_OF_CONDUCT.md). Assédio de qualquer tipo é motivo para remoção do projeto.

- Critique o código, não as pessoas.
- Discorde sem ser grosseiro: “Acho que o padrão X ficaria mais limpo aqui por causa de Y” funciona; “isso está ruim” não.
- Mantenedores que revisam o trabalho de quem contribui pela primeira vez: tenham paciência.

## Onde perguntar
- **GitHub Discussions** — perguntas abertas, ideias e coisas que você criou com o Nodaro. Prefira-o ao Issues para tudo o que não for um bug.
- **GitHub Issues** — relatos de bugs e pedidos de recursos.
- **Problemas de segurança** — relate-os por um aviso de segurança privado (security advisory) no GitHub.

Evite mandar e-mails particulares aos mantenedores sobre o projeto: as respostas públicas ajudam todo mundo. O contato particular é adequado para relatos de segurança e conflitos de interesse.

## Licença e contrato de colaborador
O repositório tem quatro níveis de licença. A maior parte do código está sob a Nodaro Sustainable Use License. O código em qualquer pasta `ee` e nos arquivos com `.ee.` no nome está sob a Nodaro Enterprise License. O `@nodaro/prompts` está sob a FSL-1.1-Apache-2.0, e `@nodaro/sdk`, `@nodaro/shared` e `@nodaro/cli` estão sob a Apache 2.0. Veja [Licença](https://nodaro.ai/docs/self-hosting/license).

**Onde o código novo entra.** Cada versão publicada dos pacotes Apache é uma concessão irrevogável. A nova engenharia de prompts, os catálogos e as predefinições ficam no `@nodaro/prompts` ou em `backend/`. Adicione ao `@nodaro/shared` só o que a API pública e o contrato do SDK precisam, como tipos, enums dos payloads da API e validação compartilhada com os usuários da API, ou o que você publica de propósito para reutilização. Diga qual dos dois casos se aplica no seu pull request.

**O contrato de colaborador.** Ao enviar uma contribuição, você concorda com o [Nodaro Contributor License Agreement](https://github.com/nodaroai/app.nodaro.ai/blob/main/CLA.md). O mesmo contrato cobre contribuições individuais e corporativas: a seção 2 dele trata da permissão do seu empregador. O bot cla-assistant pede que você o assine no seu primeiro pull request. Se você contribui em nome de um empregador, verifique se a política de propriedade intelectual dele permite isso. O contrato permite que o Nodaro licencie a sua contribuição sob qualquer uma das licenças dele, inclusive movê-la entre a Sustainable Use License e a Enterprise License.

## Frequently asked questions

### Para qual branch o meu pull request deve ir?

Crie a sua branch a partir de dev e abra o pull request para dev. Nunca crie uma branch a partir de main nem faça commits diretamente nela. As mudanças chegam à main depois de um período de observação na instância de staging.

### Preciso assinar um contrato de licença de colaborador?

Sim. Ao enviar uma contribuição, você concorda com o Nodaro Contributor License Agreement. O bot cla-assistant pede que você o assine no seu primeiro pull request, e o mesmo contrato cobre contribuições individuais e corporativas.

### Como rodo os testes?

Rode npm test na raiz do repositório para executar a suíte Vitest de todos os workspaces, ou rode um único workspace, como npm -w @nodaro/shared test. Verifique os tipos do backend e do frontend com npx tsc --noEmit antes de cada commit.

### Quando preciso de um changeset?

Quando a sua mudança afeta um pacote publicado: @nodaro/shared, @nodaro/sdk ou @nodaro/cli. Rode npx changeset e faça commit do arquivo que ele grava. Use npx changeset --empty quando a mudança não precisar de nota de versão.

### Onde faço perguntas sobre como contribuir?

Use o GitHub Discussions para perguntas abertas e ideias, e o GitHub Issues para bugs e pedidos de recursos. Relate problemas de segurança por um aviso de segurança privado (security advisory).
