
Elva: Transformando Repositórios Django em APIs para Agentes de IA
Harborops é a API de armazém para a qual estou de plantão desde 2019. Django 3.2, DRF, uma frota de Celery, um módulo django-ninja inacabado de 2023 e zero OpenAPI. A coisa mais próxima que temos de uma especificação é uma página do Confluence editada pela última vez durante o primeiro lockdown.
Eu apontei Elva https://getelva.ai para esse repositório em um domingo e tentei transformar uma parte dele em algo que um agente pudesse chamar sem que eu estivesse no Slack traduzindo nomes de campos.
Divulgação: Elva me deu 30 dias de créditos do plano Startup e pediu um artigo no meu próprio site. Eles não me pagaram, não revisaram isso e eu não havia usado o produto antes desta sessão.
O repositório que realmente apontei
Repositório privado do GitHub, ~890 arquivos Python que importam. A superfície pública é /api/v1/. Internamente, também servimos verificações de saúde através do wrapper WSGI, um consumidor de Channels para progresso de trabalho ao vivo e um caminho XML-RPC empoeirado que um cliente desktop ainda acessa.
Não há openapi.yaml. O DRF spectacular estava em um branch de spike que morreu em 2022. Se Elva só funciona quando você já tem uma especificação, este é o repositório errado. Esse era o ponto.
Elva foi lançada este mês, setembro de 2026. A maioria das ferramentas nesta categoria ainda começa a partir de um arquivo que você já escreveu. Eu queria ver o que acontece quando você começa a partir do git em vez disso.
A configuração foi npx elva init, aplicativo GitHub no repositório, então SYNC. A primeira passagem levou pouco mais de onze minutos. O número de marketing de "42 segundos" é um tamanho diferente de árvore.
Eles escanearam o código e construíram um catálogo
Elva percorreu a configuração de URL do Django e os serializadores e produziu OpenAPI 3.1 além de um catálogo. Nenhuma especificação necessária. Harborops não tinha uma.
O SYNC relatou 41 endpoints, agrupados por IA em sete coleções: Pedidos, Inventário, Remessas, Transportadoras, ASN, Faturamento, Interno. Cada coleção tem bandeiras. Lista não paginada. Descrição ausente. PII em um payload voltado para parceiros. Sem classe de autenticação.
Eu vivi neste repositório por anos e nunca tive essa tela. Não há um arquivo YAML em um branch. Um painel de toda a superfície pública, categorizado, com bandeiras nas linhas que podem te prejudicar.
Abra um endpoint e você obtém mais do que um caminho:
- a documentação interna gerada
- um editor de API sentado na especificação que eles derivaram
- uma lista de consumidores, serviços e clientes MCP que parecem chamar esta rota
- as bandeiras e as pontuações de insight para essa operação
O mapa de consumidores é a parte ambiciosa. No Harborops, ele marcou três serviços internos em GET /api/v1/orders/. Dois são reais. Um era um helper de teste que importa o serializador e nunca atinge o HTTP. Eles estão inferindo o uso a partir do repositório, não do tráfego de produção. Cedo, e ainda a ideia certa. A maioria dos catálogos não pode responder quem depende de um campo.
Insights: design, segurança, prontidão para IA
Após o SYNC, o catálogo pontuou:
| Dimensão | Pontuação |
|---|---|
| Design | 71% |
| Experiência do desenvolvedor | 54% |
| Prontidão para IA | 38% |
| Segurança | 61% |
| Desempenho | 48% |
| Pronto para agente | 41% (D) |
Isso correspondeu ao repositório. Nunca escrevemos descrições. Onze respostas usam SerializerMethodField sem help_text. Quatro rotas ainda usam AllowAny atrás de uma VPN. GET /api/v1/orders/ retornará 18.000 linhas.
Eu apliquei as correções de IA. Vinte e nove descrições apareceram. Vários campos de método ganharam tipos. A autenticação no faturamento foi documentada. A prontidão para IA subiu para 67%. Eu li cada descrição gerada nos 14 endpoints que mais tarde coloquei em um contrato.
Dois se mantiveram. POST /api/v1/orders/{id}/ship/ disse corretamente que cria uma remessa, precisa de carrier e service_level, e não é idempotente. GET /api/v1/inventory/skus/ corretamente separou on_hand de available.
Dois estavam errados de uma maneira que importa para os agentes. hold_code é um CharField que tratamos como um enum (WEATHER, SHORT, CREDIT, DAMAGE, CUSTOMS, OTHER). O texto gerado o chamou de "um identificador de retenção de armazém numérico usado pelo loop de colocação do WMS." Isso é bin_hold_id em um serializador diferente. eta foi chamado de "timestamp de entrega garantida." É uma estimativa do transportador.
As pontuações são honestas. A prosa gerada é um primeiro rascunho. Revise-a como um pull request de alguém que nunca esteve no armazém.
O que o scanner perdeu
Os 41 endpoints eram reais. Eu os verifiquei contra apps/*/urls.py. As perdas são os dados mais úteis.
Deveria ter capturado estes:
-
POST /api/v1/webhooks/stripe/embilling/hooks.py. Função de visualização@csrf_exempt, incluída através de um pequeno pacote local. A inclusão nunca foi resolvida. -
POST /api/v1/inventory/bulk-adjust/. Um@actiondo DRF cujourl_pathé uma constante importada deinventory.constants. A ação existe. O caminho nunca apareceu. -
GET /api/v1/reports/cycle-count.xlsx. UmAPIViewque retorna umFileResponse. Sem serializador. Descartado.
Perdas justas:
-
GET /internal/readyeGET /internal/live, montados no wrapper WSGI, não nas URLs do Django. -
ws/jobs/{id}/, um consumidor de Channels. -
/legacy/xmlrpc/, não REST.
ViewSets do DefaultRouter padrão escaneiam bem. Um aplicativo Django de cinco anos não é apenas isso. Eu não encontrei um controle de "este caminho existe, adicione-o" na primeira passagem, então eu corrigi a especificação manualmente. A descoberta a partir da fonte é a inovação. Um clique para adicionar as últimas rotas bagunçadas é a lacuna.
Contratos são o recurso sério
Este é o ponto onde parei de tratar o domingo como uma sessão de brinquedo.
Você escolhe um caso de uso (parceiro, interno, público ou agente de IA / MCP), escolhe ferramentas e campos, e pode deixar a IA propor o corte. Campos ocultos permanecem ocultos. PII pode ser redigido. A partir desse contrato, você gera OpenAPI e escolhe um destino: uma ferramenta de documentação, Postman, um servidor simulado ou um servidor MCP.
Eu construí 3pl-partner v1 para o 3PL que já consulta remessas. Quatorze endpoints. Em GET /api/v1/shipments/{id}/ eu escondi internal_cost e margin_bps, e redigi customer_email.
A parte que importa após a publicação: se a fonte mudar, Elva compara o novo catálogo com o contrato, notifica você sobre desvios e você revisa antes que uma nova versão seja lançada. O contrato é versionado. Os artefatos de destino não se movem silenciosamente sob um parceiro.
Eu testei isso da maneira rude. Branch, renomear tracking_number para carrier_tracking.
A utilização de ferramentas como Elva pode revolucionar a forma como empresas brasileiras documentam e preparam suas APIs para integração com agentes de IA. Isso pode aumentar a eficiência e a segurança na comunicação entre sistemas, além de facilitar a adoção de práticas de AI readiness.


