Vaga de dev sênior. R$ 5.000 no primeiro mês, R$ 7.500 do segundo em diante.
Este desafio existe por um motivo só: eu quero ver como você pensa a fronteira entre as partes de um sistema, e quero te ouvir defender isso depois. O código importa menos do que a explicação.
Tempo máximo: 2 dias. Se passou disso, você fez a mais.
Um mini "Studio" de conteúdo. O usuário digita um tema e o sistema gera três coisas:
- Roteiro (texto): um roteiro curto de 30 segundos sobre o tema
- Narração (áudio): o roteiro falado
- Capa (imagem ou vídeo, escolha sua): o visual do post
Cada geração custa crédito. O usuário compra crédito antes de gerar.
É isso. Não é pra ser um produto, é pra ser um esqueleto honesto de um.
O domínio não pode conhecer HTTP, SDK de provider, banco de dados nem framework. Se o seu caso de uso importa next/server ou o SDK da OpenAI, a fronteira está no lugar errado.
texto, áudio e imagem são módulos separados. Cada um tem a sua porta e os seus adapters. O módulo de áudio não sabe que existe um módulo de texto.
Providers sugeridos (você não precisa gastar dinheiro, veja o item 3):
| Módulo | Providers |
|---|---|
| Texto | OpenRouter |
| Áudio | ElevenLabs, Fish Audio |
| Imagem/vídeo | livre escolha |
Um adapter real e um fake determinístico. O fake é o que faz o projeto rodar sem chave de API nenhuma e é o que os testes usam.
Trocar de provider tem que ser variável de ambiente. Sem tocar em domínio, sem tocar em caso de uso, sem if provider === 'x' espalhado.
Bônus real (não obrigatório): dois adapters reais no mesmo módulo, para eu ver como você lida com dois SDKs que discordam sobre o formato da resposta.
- Um usuário com saldo de créditos. Pode ser um usuário fixo hardcoded, não quero auth completa.
- Cada operação tem um custo. Gerar texto custa X, áudio custa Y, imagem custa Z.
- Saldo insuficiente é erro de domínio, e o provider não pode ser chamado.
- Compra de crédito: Stripe em test mode, ou um endpoint fake que simula o webhook. Tanto faz. O que eu olho é a fronteira: pagamento é adapter, crédito é domínio.
- O webhook precisa ser idempotente. Mesmo evento entregue duas vezes não credita duas vezes.
- LP: uma página. O que é o produto, quanto custa, um CTA.
- App: input do tema, botão gerar, o resultado (texto na tela, player de áudio, imagem), saldo de créditos visível, botão de comprar crédito.
Não precisa ser design de agência. Precisa ter cuidado. UI/UX entra na avaliação e eu vou reparar em espaçamento, hierarquia, estado de loading e o que acontece quando dá erro.
Domínio e casos de uso testados sem rede, usando os adapters fake.
Não quero cobertura alta. Quero os testes que provam que a fronteira é real, ou seja, aqueles que passariam mesmo se todo provider do mundo saísse do ar.
TypeScript é obrigatório no núcleo. Framework, banco, ORM, gerenciador de pacote e libs: escolha sua, e eu vou te perguntar o porquê de cada uma.
Se quiser usar Python em alguma parte (um pipeline, um worker), pode. Aqui na Doti o backend de análise é Python e a aplicação é TypeScript, então esse tipo de mistura é o nosso dia a dia.
Cortei essas coisas de propósito. Se você fizer, eu vou considerar sinal ruim de priorização:
- Autenticação completa, cadastro, recuperação de senha
- Multi-tenant, times, permissões
- Deploy, CI/CD, Terraform, Kubernetes
- Internacionalização
- Painel admin
- Testes E2E
docker-composecom seis serviços
Se algo do escopo principal não couber nos 2 dias, corte e escreva no README o que você cortou e por quê. Cortar bem é parte da avaliação. Entregar tudo pela metade é pior do que entregar menos coisa inteira.
A gente trabalha com Claude Code o dia inteiro. Use o que você quiser: Claude, Cursor, Codex, o que for.
Só existe uma condição: você precisa conseguir defender cada linha. Na conversa eu vou apontar para um arquivo aleatório e perguntar por que está daquele jeito. "A IA escreveu" encerra a entrevista.
- Repo público seu. Se preferir privado, dá acesso para
@coelho-doti. - README respondendo, em texto corrido mesmo:
- Como rodar do zero, com e sem chaves de API
- Quais são as fronteiras do sistema e por que cada uma existe (diagrama, lista, o que for mais claro)
- O que você cortou e por quê
- O que quebraria primeiro se isso fosse para produção com mil usuários
- Me manda o link no DM.
45 minutos, e é aqui que a vaga é decidida. Eu vou te pedir para:
- Adicionar um provider novo ao vivo, ou me mostrar exatamente onde você tocaria
- Defender uma decisão que eu vou atacar (e às vezes eu vou estar errado, quero ver se você segura)
- Dizer o que faria diferente com 2 semanas em vez de 2 dias
Não decore resposta. Eu quero ouvir o raciocínio, inclusive o "isso aqui eu fiz mal feito porque estava sem tempo".
Critérios de avaliação: AVALIACAO.md
Dúvida sobre o enunciado: abre uma issue nesse repo. Eu respondo em público, ajuda todo mundo.