Feature Chain — rastreie o fullstack com um único operationId

Quais arquivos precisam ser modificados para alterar uma funcionalidade? Informe um operationId e a resposta aparece.


O problema

Em uma aplicação fullstack, uma “funcionalidade” nunca está em um único arquivo.

Imagine que você precisa modificar a funcionalidade “Aceitar Proposta (AcceptProposal)”. Ela existe na especificação da API, na lógica de serviço, no schema do banco de dados, na política de autorização, no diagrama de transição de estados, nas chamadas de funções externas, nos cenários de teste e no frontend.

Tradicionalmente, havia duas formas de mapear esse escopo completo:

  1. Executar grep dezenas de vezes
  2. Rastrear o código manualmente

Ambas são lentas, ambas resultam em omissões. Rastrear referências que cruzam camadas — da especificação da API para o serviço, do serviço para o schema do banco, do serviço para a política de autorização — sem deixar nada passar é, na prática, muito difícil para um ser humano.

Mas se cada camada já referenciar simbolicamente as outras, basta seguir essas referências para que o escopo completo se revele automaticamente.


O que é o Feature Chain

O Feature Chain extrai todos os nós de fonte conectados a uma funcionalidade de API (operationId).

Partindo de um único operationId, ele percorre as referências simbólicas entre fontes e exibe de uma vez todos os arquivos relacionados com seus números de linha. Dezenas de execuções de grep são substituídas por um único comando.

fullend chain AcceptProposal specs/
── Feature Chain: AcceptProposal ──

  OpenAPI    api/openapi.yaml:296                          POST /proposals/{id}/accept
  SSaC       service/proposal/accept_proposal.ssac:19      @get @empty @auth @state @put @call @post @response
  DDL        db/gigs.sql:1                                 CREATE TABLE gigs
  DDL        db/proposals.sql:1                            CREATE TABLE proposals
  DDL        db/transactions.sql:1                         CREATE TABLE transactions
  Rego       policy/authz.rego:3                           resource: gig
  StateDiag  states/gig.md:7                               diagram: gig → AcceptProposal
  StateDiag  states/proposal.md:6                          diagram: proposal → AcceptProposal
  FuncSpec   func/billing/hold_escrow.go:8                 @func billing.HoldEscrow
  Gherkin    scenario/gig_lifecycle.feature:4              Scenario: Happy Path - Full Gig Lifecycle
  Gherkin    scenario/gig_lifecycle.feature:42             Scenario: Unauthorized Access

A estrutura completa de uma funcionalidade aparece em uma única tela. Camadas sem conexão não são exibidas.


Por que isso é possível

Não é mágica. É possível porque as fontes já se referenciam mutuamente.

No framework fullend, cada camada SSOT (Single Source of Truth) aponta simbolicamente para as outras:

  • SSaC @get Model.Method → tabela DDL
  • SSaC @auth action resource → política de autorização Rego
  • SSaC @state diagramID → diagrama de estados Mermaid
  • SSaC @call pkg.Func → implementação Func Spec
  • OpenAPI operationId → nome do arquivo SSaC
  • Gherkin action step → operationId
  • STML endpoint → path OpenAPI

Essas referências foram originalmente projetadas para o crosscheck — uma ferramenta que valida a consistência entre SSOTs. Como o crosscheck já faz o parsing dessas referências, reutilizar a mesma infraestrutura permite extrair o feature chain com uma simples travessia de grafo.


Caminho de travessia

Partindo do operationId como ponto de entrada, o grafo de referências se expande assim:

operationId (ponto de entrada)
├── OpenAPI → path + method
├── SSaC → arquivo da função de serviço
│   ├── @get → tabelas DDL
│   ├── @auth → regras de política Rego
│   ├── @state → transições no Mermaid stateDiagram
│   ├── @call → implementações Func Spec
│   └── @publish → assinantes de fila
├── Gherkin → cenários que referenciam o operationId
└── STML → arquivos de frontend que referenciam o endpoint

Cada ramificação segue apenas um nível de referência simbólica. É uma travessia em largura, não em profundidade. Tudo o que uma funcionalidade deixa de rastro em cada camada é revelado de uma vez.


O que isso muda

Mapeamento do escopo de modificação

“Onde preciso mexer para corrigir esta funcionalidade?”

Para responder a essa pergunta, lemos código, executamos grep, perguntamos a colegas. O Feature Chain substitui essa pergunta por um único comando. Nenhum arquivo escapa — desde que haja referência simbólica.

Modificação de código com IA

Ao delegar uma modificação de funcionalidade para uma IA, o maior desafio é “comunicar o escopo da modificação”. Para que a IA faça a alteração corretamente, todos os arquivos relevantes precisam estar na janela de contexto — mas é o desenvolvedor quem precisa decidir quais arquivos são relevantes.

Com o Feature Chain, isso muda. Basta informar um operationId para que o escopo completo da modificação seja identificado automaticamente. O contexto a ser passado para a IA fica pronto, sem omissões.

Code review

Ao revisar um PR, a suspeita “se esta funcionalidade foi alterada, aquele arquivo também deveria ter mudado, não?” pode ser verificada imediatamente ao comparar com o chain. A estrutura detecta inconsistências entre camadas no lugar do desenvolvedor.

Onboarding

Quando um novo desenvolvedor diz “quero entender como o AcceptProposal funciona”, basta mostrar um Feature Chain. Da API ao banco de dados, da política de autorização aos cenários de teste — toda a topologia da funcionalidade aparece de uma vez.


Por que operationId?

A escolha do ponto de entrada importa. O Feature Chain optou pelo operationId.

O motivo é simples. Em uma aplicação fullstack, a unidade de uma funcionalidade é o endpoint de API. O usuário clica em um botão, a API é chamada, essa API executa a lógica de serviço, lê o banco, verifica a autorização e realiza a transição de estado. O ponto de partida de todo esse fluxo é o operationId.

O operationId já está definido na especificação OpenAPI e é um nome compartilhado por toda a equipe. Quando alguém diz “preciso modificar o AcceptProposal”, o desenvolvedor backend, o desenvolvedor frontend e o QA pensam na mesma coisa. O design do Feature Chain é justamente usar esse nome universal para atravessar toda a stack.


Pré-requisitos

Para que o Feature Chain funcione, existem condicionantes:

  1. As fontes precisam se referenciar simbolicamente. As diretivas @get, @auth, @state e @call do SSaC precisam apontar explicitamente para outros SSOTs. Se a referência for implícita — por exemplo, se o nome de uma tabela do banco existir apenas como string no código — não é possível rastrear.

  2. O crosscheck precisa passar. O Feature Chain segue referências simbólicas, então se uma referência for inválida, o resultado será incorreto. O crosscheck garante a consistência das referências; o Feature Chain executa a travessia sobre essa base.

É por isso que o Feature Chain não é uma ferramenta de uso geral. Ele não pode ser aplicado a qualquer projeto. Funciona apenas em projetos onde as referências entre fontes são projetadas explicitamente — estruturas como o fullend, onde os SSOTs apontam uns para os outros de forma explícita.


Futuro: GEUL + SILK

Atualmente, o Feature Chain percorre os parsers de cada SSOT separadamente. Ele chama o parser do SSaC, do DDL, do Rego e do Mermaid individualmente e combina os resultados.

Quando todos os SSOTs forem convertidos para o grafo GEUL, o Feature Chain se tornará uma consulta de índice único. Com a operação bitwise AND do SIDX do SILK, todos os nós conectados a um operationId poderão ser extraídos em uma única consulta.

Da travessia por parser para a consulta em grafo. A interface do Feature Chain permanece a mesma, mas o interior muda radicalmente.


Conclusão

Em uma aplicação fullstack, uma “funcionalidade” não está em um único arquivo. Ela se distribui por múltiplas camadas, e essas camadas se referenciam mutuamente. O Feature Chain percorre essas referências e extrai automaticamente o escopo completo de uma funcionalidade.

Informe um operationId e — da especificação da API ao schema do banco, das políticas de autorização aos cenários de teste — dezenas de execuções de grep são substituídas por um único comando.

Código: github.com/park-jun-woo/fullend