Pular para conteúdo

0014 — Fato de outro repo é importado no build, não copiado

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-07-16 · Decidido em: 2026-07-16

Contexto

A 0013 abriu transclusão para fato do mesmo repo e manteve "cross-repo é link, sempre". O caso que sobrou é o mais concreto que temos: o runbook de implantação de um vertical vive entre dois apps — o que ele implanta é seu, mas o contrato de ingestão que ele consome é do hub. O dev quer (com razão) a página única: mostrar a integração à equipe sem saltar entre sites.

O diagnóstico mudou a pergunta. O hub publica site, mas:

  • não publica o OpenAPI que ele já gera (o step está comentado no docs.yml);
  • não tem docs/public/ — nada dele é público no sentido do §5;
  • o contrato PUT /api/v1/xadm vive espalhado em dez arquivos de prosa.

Não havia o que linkar. O consumidor re-digitou a tabela de campos, o exemplo e a lista de origens aceitas — e isso virou o exemplo-que-mente que a 0.20.2 nomeia. A cópia era sintoma; a causa é o dono que não publica. Uma regra que pare no consumidor pune o sintoma.

E existia um caminho que a constituição não tinha: o --8<-- não atravessa repositório, mas o build atravessa.

Decisão

Fato de outro repo: link, importação no build, ou nada — nunca cópia.

  • O dono publica (docs.yml): o .md cru vai para site/raw/ e daí para a raiz do prefixo do app — rclone copy site/raw "garage:docs-sites/<slug>/raw", aditivo, todo push. A URL fica determinística: https://docs.xadm.biz/aplicacoes/<slug>/raw/<fato>.md.
  • O consumidor importa antes do build: curl -fsSL … -o docs/_importado/<fato>.md, e embute com --8<--. O docs/_importado/ é efêmero (.gitignore + exclude_docs:) — versioná-lo o tornaria de volta uma cópia.

  • Publicar o fato é obrigação do DONO, não do consumidor. Fato que mais de um repo precisa mostrar o dono expõe como artefato consumível: o OpenAPI gerado e/ou o arquivo-fato em raw/. Se o dono não publica, o consumidor linka e cobra a publicação — a dívida é do dono.

  • Quem rege a evolução de um repo não vira dono dos fatos dele. Um vertical pode dirigir a evolução do hub; isso diz quem escreve o PR, não quem possui o fato. O dono continua o repo onde o fato é verdade (código, schema, spec gerado): o projeto-mãe cria o arquivo-fato e o importa aqui.

Raiz, não versão: o raw/ é contrato entre apps, não conteúdo versionado — o mesmo critério que já põe o app.json na raiz. O consumidor importa o atual, e a doc dele acompanha o dono no próximo build.

Alternativas consideradas

  • Manter "cross-repo é link". Rejeitada: é a regra que produziu a cópia, porque não havia o que linkar. Dois feedbacks seguidos bateram no mesmo ponto.
  • swagger-ui remoto apontando o OpenAPI do dono (mesma origem, sem CORS). Boa e mais barata — e continua sendo o caminho certo para o contrato REST em si, que é derivável. Insuficiente como norma geral: não cobre o fato que a geração não produz (a lista de origens aceitas vive no código, não no spec).
  • Pinar a versão do fato (/<app>/<X.Y.Z>/raw/…), como o consumidor pina o bi-commons. Rejeitada: a doc passaria a mostrar o contrato de uma versão que pode não ser a que está no ar — doc que mente com carimbo de conforme —, e o pin envelhece calado, que é o drift que este padrão existe para matar. Quem precisa de contrato estável resolve com versão de API no dono (/api/v1/), não com pin na doc.
  • Formalizar "projeto-mãe" como dono editorial do fato. Rejeitada: o hub é compartilhado (§8) — mais de um vertical consome o mesmo PUT /api/v1/xadm. Se o projeto-mãe vira dono, o hub passa a ter um dono por consumidor, que é exatamente o caos que o §1.9 evita.

Consequências

  • O runbook de implantação pode ser uma página — topologia, fluxo e o contrato do hub — sem uma linha de cópia. O caso que motivou dois feedbacks fica atendido.
  • A doc do consumidor muda sem PR dele. É o objetivo (§2 quer estado atual), mas é a consequência a aceitar conscientemente. curl -f faz o build falhar se o dono despublicar ou renomear: o alerta é o vermelho, não um leitor descobrindo meses depois.
  • Dívida do hub de integração (pendência humana, dois repos): ele gera OpenAPI e não o publica, e não expõe arquivo-fato. Enquanto isso, o vertical linka — não copia. A ordem certa é o dono publicar primeiro; o vertical, que rege a evolução dele, é quem faz esse PR.