ADR-016 — Extração de ui-web/ui-native, Storybook independente e docs-site viva (reverse-engineered)
- Status: Inferred / documentado retroativamente — não é um ADR redigido antes da implementação.
- Data do registro: 2026-08-30 (a implementação ocorreu em 2026-08-29/30, na branch
feat/component-atomicity-storybook, mergeada emmasterno commit115ffe2antes deste documento existir). - Decisores: Owner, via pedidos diretos em chat, fora do fluxo SDD formal (sem CR/IS/EP aprovado como ponto de partida).
- Relacionado:
SPEC-ARCH-BOUNDARIES-001v2.1,SPEC-ARCH-QUALITY-001v2.1,CR-COMPONENT-ATOMICITY-001,CR-VERCEL-DEPLOYS-001,CR-API-ERROR-CATALOG-001,CR-SDD-DASHBOARD-001.
Nota de proveniência
Este documento foi produzido pela skill raizfc-reverse-engineer-branch para reconstruir, em linguagem de produto/arquitetura, o que a branch feat/component-atomicity-storybook entregou. A branch não partiu de um CR/IS/EP aprovado — foi trabalho direto por pedido do owner em chat. As três CRs relacionadas (CR-COMPONENT-ATOMICITY-001, CR-VERCEL-DEPLOYS-001, CR-API-ERROR-CATALOG-001) foram escritas depois da implementação, a pedido do próprio owner, e cobrem apenas o trabalho futuro (expansão de cobertura de componentes, configuração de deploy Vercel, catálogo de erros por endpoint) — nenhuma delas descreve o que já foi entregue. Este ADR existe para fechar essa lacuna: registrar o que já está em produção, sem inventar aprovação formal que não existiu.
Cenário / objetivo observado
Sequência de pedidos diretos do owner nesta sessão, sem CR prévio:
- Uma ferramenta de "documentação viva" a partir de specs + código → escolhido Docusaurus sobre
docs/. - Identidade visual RaizFC na doc (logo, cores, tipografia de
assets/new_brand/edocs/03_ux/design_tokens.md, sem reinventar tokens). - Referência de código: TypeDoc para
packages/contractse OpenAPI enriquecido a partir dos DTOs reais. - Visibilidade de componentes de front "tipo Storybook" — tentativa inicial embutida na doc (iframe/MDX), revertida explicitamente pelo owner ("achei que ia ficar dentro da doc como um plugin", depois "pode deixar o storybook como um projeto separado, com um link na doc pra ele, via variável de ambiente").
- Promoção do Storybook a app deployável de verdade, separado ("vou deployar em aplicação separada") — o que forçou extrair os componentes de
apps/web/apps/mobilepara pacotes compartilhados, já que Storybook não pode importar código de dentro de outro app sem violarpackage_boundaries.md. - Link para a doc oficial no dashboard SDD (
tools/sdd-dashboard).
Contexto técnico
packages/uijá continha ~30 componentes headless (sem React, verIS-MVP-17.1/17.2), mas sóButtoneStatusChiptinham adapter visual real, duplicado dentro deapps/web/src/shared/ui-kiteapps/mobile/src/shared/ui-kit.- Não existia pacote de design-system compartilhado entre React DOM e React Native — cada app tinha sua própria cópia do
ThemeProvider/ThemeContext. package_boundaries.md(SPEC-ARCH-BOUNDARIES-001) já proibia um app importar arquivo de outro app diretamente, o que tornava impossível o Storybook simplesmente importarapps/web/src/shared/ui-kitsem violar a spec.
Arquivos relevantes
packages/ui-web/epackages/ui-native/(novos pacotes) —Button,StatusChip,ThemeProvider/ThemeContextextraídos deapps/webeapps/mobile, com persistência própria por plataforma (localStorageno web,expo-secure-storeno native).apps/storybook/(novo app) — Storybook 10 +@storybook/react-vite, consomepackages/ui-webvia alias de source (não viadist/, para evitar duas instâncias deReact.Context).tools/docs-site/(novo projeto, fora do workspace pnpm, mesmo padrão detools/sdd-dashboard) — Docusaurus sobredocs/, TypeDoc em/code/contracts, Redocusaurus em/code/api, três links de navbar (Storybook, app em produção, SDD Board) resolvidos por variável de ambiente (STORYBOOK_URL,APP_URL,SDD_BOARD_URL, defaultlocalhost).services/api/scripts/generate-openapi.ts(novo) — enriquece o Swagger gerado pelo NestJS com schemas reais de request/response, via parsing de AST TypeScript +ts-json-schema-generatorsobre os tipos de@raizfc/contracts(que sãotypealiases sem presença em runtime, então o@nestjs/swaggersozinho não os alcança).services/api/src/bootstrap.ts— monta Swagger UI em/docs, só fora de produção.tools/sdd-dashboard/app.py— botão/link para a doc oficial (DOCS_URL), na sidebar e na aba Docs.docs/06_architecture/package_boundaries.mdedocs/06_architecture/testing_quality_architecture.md— bump 2.0 → 2.1, já formalizamui-web/ui-native/storybookcomo tiers do monorepo.scripts/check-workspace-boundaries.mjs— corrigido um bug pré-existente (checagem deDEEP_INTERNAL_IMPORTsó reconhecia subpath exports de@raizfc/config, hardcoded) para generalizar e permitir os subpaths novos deui-web(theme-tokens.css,ui-kit.css).
Comportamento observado
- A referência de API (
tools/docs-site→/code/api) hoje mostra schemas reais de request/response para as 225 operações doservices/api, mas todo endpoint usa a mesma resposta de erro genérica (default) — não há mapeamento de erro de domínio por rota. É exatamente o gap queCR-API-ERROR-CATALOG-001propõe fechar. - O Storybook publicado cobre 2 de ~30 componentes de
packages/ui(Button,StatusChip) — cerca de 3% de cobertura real do design system. É o gap central deCR-COMPONENT-ATOMICITY-001. - Web e mobile não compartilham a mesma instância de Storybook ainda — só existe
apps/storybookconsumindopackages/ui-web(React DOM). Não há integraçãoreact-native-webnem@storybook/react-native, apesar do pedido explícito do owner ("web e mobile vão estar no mesmo storybook"). - As URLs reais de deploy (
STORYBOOK_URL,SDD_BOARD_URL,APP_URL) nunca foram configuradas em nenhum ambiente Vercel real — o navbar do docs-site ainda cai nos defaultslocalhostem qualquer deploy publicado até agora.
Dependências e risco
- Dois bugs de build só apareceram em produção, depois do merge (branch já estava em
master): o build dotools/docs-sitena Vercel quebrou porquepackages/contracts/dist(gitignored, nunca comitado) nunca era buildado antes deopenapi:generaterodar; o build doapps/storybookquebrou pelo mesmo motivo, faltandopackages/ui/dist. Ambos corrigidos depois do merge, direto emmaster, sem passar por PR (commits4c5c692e476c84a). Isso indica que a branch não foi validada contra um checkout limpo equivalente ao da Vercel antes do merge — o CI do monorepo não cobre esses dois builds. package_boundaries.mdetesting_quality_architecture.mdsão specsApprovede foram alteradas (bump de versão) sem passar por Impact Analysis → IS → EP formal antes da implementação — a mudança estrutural já é canônica nas specs, mas o processo que normalmente precede uma mudança de spec Approved não foi seguido aqui.CR-COMPONENT-ATOMICITY-001,CR-VERCEL-DEPLOYS-001eCR-API-ERROR-CATALOG-001tiveramhuman_approval.status: approved(escopo geral) nesta mesma sessão em 2026-08-30, masready_gatecontinuapendingnas três — decisões sensíveis reais (fonte de verdade do mapeamento de erros, mecanismo de unificação web/mobile no Storybook,vercel.jsonvs. documentação de dashboard, acesso público vs. protegido para docs-site/storybook) seguem em aberto e não foram resolvidas pela aprovação de escopo.
Impacto de arquitetura
ui-web/ui-nativepassam a ser um tier formal entrepackages/ui(headless) e os apps (web/mobile/storybook), documentado empackage_boundaries.mdv2.1: nenhum app pode importar componente de outro app diretamente, todos passam pelo adapter compartilhado.apps/storybooké tratado como consumidor read-only deui/ui-web— sem componente próprio, sem import direto deweb/mobile.- O boundary-checker (
scripts/check-workspace-boundaries.mjs) teve uma correção de escopo mais amplo que o necessário só para este branch: o bug doDEEP_INTERNAL_IMPORTafetava qualquer pacote com subpath exports, não sóui-web— a correção generaliza a checagem para todo o monorepo, não é local a esta mudança.
Itens não resolvidos ou assumidos (inferidos, não formalizados)
- Não há decisão registrada sobre se este trabalho deveria ter passado por Impact Analysis → IS → EP antes de tocar em specs
Approved— não passou, e isso não foi corrigido retroativamente por este ADR (correção de processo, não de código). - Não há decisão registrada sobre se os dois bugs de deploy pós-merge deveriam ter bloqueado o merge do PR #88 — não bloquearam; o CI local do monorepo passou porque não simula um checkout limpo sem os
dist/gitignored dos pacotes workspace. - Cobertura completa do Storybook, unificação web/mobile numa única instância, e configuração real dos três deploys Vercel ficam para
CR-COMPONENT-ATOMICITY-001eCR-VERCEL-DEPLOYS-001— ambas aprovadas em escopo,ready_gatepending.
Recomendação
- Não é necessário reabrir este trabalho como EP formal retroativo — as specs afetadas já foram bumped e o comportamento já está em produção; o valor de formalizar agora seria auditoria/rastreabilidade, não desbloquear algo.
- Priorizar resolver os
pending_decisionsdeCR-COMPONENT-ATOMICITY-001eCR-VERCEL-DEPLOYS-001antes de expandir mais escopo em cima deles. - Considerar adicionar ao CI do monorepo uma validação de build "checkout limpo" para
tools/docs-siteeapps/storybook(os doisdist/gitignored que já causaram quebra em produção), para não depender de descobrir esse tipo de gap só no deploy real.