Guia da Plataforma FAPESBInício
Z Future

Versão 1.0 · 10/11/2026 · rascunho para discussão

FAPESB · Edital 027/2025

Quatro empresas, um só produto.

Cada empresa constrói o seu módulo no framework que domina. Para quem usa, é um sistema só: um endereço, um login, uma identidade visual.

Ver em uma imagem
  • Um app por módulono framework de cada empresa
  • O comum é pacote@fapesb/* no Verdaccio
  • Acordo nas fronteiraso comitê das 4 decide
TEORIA DOS CONJUNTOS EM 10 SEGUNDOS

O que vai para onde?

Vão para o Verdaccio

Código reutilizável. Nunca roda sozinho: entra num app no build.

  • @fapesb/shellcabeçalho, menu, rodapé
  • @fapesb/estiloSass + gov.br
  • @fapesb/contratostipos das APIs
  • @fapesb/baselogin, erros, logs
P ∩ C = ∅Nada é pacote e contêiner ao mesmo tempo.

Em uma imagem

A plataforma inteira, para entender olhando

Siga os números de 1 a 8. O resto deste guia detalha cada parte.

Resumo da plataforma: o usuário entra por um endereço e um login; o gateway manda para quatro módulos, cada um com app, API e banco PostgreSQL 18 próprios; os módulos conversam só pela API; o comum vem em pacotes do Verdaccio; cada empresa trabalha no seu Git e publica nos servidores da FAPESB.
Abrir em tela cheia · baixar a imagem (PNG)

1 · O mapa

O caminho de um projeto, do edital à prestação de contas

Cada etapa é um módulo com dono. O proponente não sabe, nem precisa saber, que quatro empresas trabalham por trás: para ele, é um sistema só.

Z FutureMyappnowMTMEmpresa Dsistema externo
Passe o mouse nas setas para ver o que trafega. O edital exige essas ligações: a contratação começa "a partir de projetos aprovados e finalizados" R1 p.50 · Anexo 2 §2.2.1 e se comunica "com os módulos de submissão e prestação de contas" R1 p.52 · Anexo 2 §2.2.8.
Ver o mapa em texto
  • Submissão (Z Future) → Contratação (Myappnow): projeto aprovado, proponente, edital, orçamento e cronograma.
  • Contratação → Prestação de Contas (MTM): instrumento, orçamento aprovado, alterações, status e pagamentos.
  • Prestação de Contas → Monitoramento (Myappnow): execução financeira, prazos e situação.
  • Contratação → SEI: instrumento para assinatura e tramitação.
  • Bolsas (Empresa D) → Prestação de Contas: bolsista, vínculo, vigência e prazos.
  • Todos os módulos usam o Keycloak da FAPESB para login.

Quem faz o quê

  • Z Future: submissão, enquadramento e mérito (F1–F6) e o pacote visual comum. Desafio 5.1.2.1 R1 p.7.
  • Myappnow: contratação e monitoramento ("Contratos 4.0"). Desafio 5.1.2.2 R1 p.7. Contato: Silvio.
  • MTM Tecnologia: prestação de contas e o Keycloak da FAPESB. Responsável pela autenticação: Gustavo.
  • Empresa D: provavelmente bolsas, a confirmar. O desafio de bolsas "envie dados para o sistema de prestação de contas" R2 p.8-9 · §5.1.4.1.

Por que precisamos de regras comuns

Os sistemas trocam dados e compartilham login, perfis e chaves: CPF, código do edital e números do pedido e do instrumento. Uma mudança feita sozinha quebra outro sistema. E o código fica com a FAPESB, que recebe "acesso ao código-fonte, documentação técnica, modelos de IA" R1 p.32 · §23.4. Quatro jeitos diferentes de construir multiplicam o custo de quem vai manter.

2 · A montagem

Um domínio, um app por módulo, cada um no seu framework

Cada empresa publica o app do seu módulo como imagem de contêiner. Um gateway Nginx recebe todo o tráfego do domínio e encaminha cada prefixo de URL para o app certo. O Anexo 3 já prevê o "Nginx (como servidor de aplicação e proxy reverso)" R1 p.57 · Anexo 3 §2.2. Nenhum framework manda nos outros.

Z FutureMyappnowMTMEmpresa Dplataforma (comum)
Dentro do módulo, a navegação é instantânea. De um módulo para outro, a página recarrega, mas o login continua o mesmo. O Next chama esse modelo de Multi-Zones e diz que ele "allows other applications on the domain to use their own choice of framework".

Por que um app por módulo, e não um app único com os módulos dentro

Montar tudo num app só, com cada módulo instalado como pacote (por exemplo, Nuxt Layers), tem dois problemas. Obriga todas as empresas a usar o mesmo framework. E cada mudança de qualquer módulo exige gerar e publicar o app inteiro de novo. O artigo de referência sobre micro-frontends, de Cam Jackson no site de Martin Fowler, chama isso de integração em tempo de build e é direto: "we would recommend strongly against this kind of approach". O mesmo artigo recomenda dividir o produto por página, cada uma "owned end-to-end by a single team".

Avaliação da Z Future com base no artigo de Fowler e na documentação de single-spa, Module Federation e Next Multi-Zones. "Simples para time iniciante" pesa muito aqui: as equipes ainda estão aprendendo projetos grandes.

O que a sua empresa entrega

  • O app do seu módulo (Nuxt, Next ou Angular), servido debaixo do seu prefixo, como imagem de contêiner.
  • A API do módulo, com o seu banco.
  • Os contratos (OpenAPI) das APIs que outros consomem, em fapesb-contratos.
  • Testes, documentação e diagramas C4 do módulo.

O que a sua empresa não faz

  • Tela de login, cadastro ou senha: é o Keycloak.
  • Cabeçalho, menu e rodapé próprios: vêm prontos do @fapesb/shell.
  • Cores, fontes e medidas próprias: vêm do @fapesb/estilo e do DSGov.
  • Acesso ao banco de outra empresa: só por API.

Como cada framework roda debaixo do seu prefixo

FrameworkConfiguração do prefixoComponentes do governo
Nuxt (Vue) · Z Futureapp.baseURL: '/submissao/' ou NUXT_APP_BASE_URL (docs)@govbr-ds/webcomponents-vue
Next (React)basePath: '/contratacao' (docs)@govbr-ds/webcomponents-react
Angular<base href="/prestacao/"> no build (docs)@govbr-ds/webcomponents-angular

Os três wrappers do DSGov estão na versão 2.6.0. Angular precisa de justificativa no ADR, porque o Anexo 3 da FAPESB cita só "Vue.js/React.js" R1 p.57. O próprio R2 lista Angular para outra entidade R2 p.73 · Anexo 3 §2.3.

# gateway da plataforma: um domínio, um app por módulo
location /submissao/        { proxy_pass http://submissao-web:3000; }   # Nuxt · Z Future
location /contratacao/      { proxy_pass http://contratacao-web:3000; } # framework da Myappnow
location /prestacao/        { proxy_pass http://prestacao-web:3000; }   # framework da MTM
location /bolsas/           { proxy_pass http://bolsas-web:3000; }      # Empresa D
location /api/submissao/    { proxy_pass http://submissao-api:8080/; }  # uma regra por API
location /_plataforma/shell/ { root /srv/plataforma; }                  # @fapesb/shell compilado
location /                   { root /srv/plataforma/portal; }           # página inicial comum

Passo a passo: colocar o seu módulo no ar

  1. Crie o app a partir do modelo do seu framework. Há um repositório-modelo para Nuxt, Next e Angular, com prefixo, shell, estilo, login e CI já configurados. Você cria o seu projeto no seu próprio GitHub ou GitLab.
  2. Configure o prefixo do módulo. Exemplo no Next:
    // next.config.ts
    export default { basePath: '/contratacao' }
  3. Aponte o escopo @fapesb para o Verdaccio. O token fica no cofre do CI, nunca no Git.
    # bunfig.toml
    [install.scopes]
    "@fapesb" = { token = "$FAPESB_NPM_TOKEN", url = "https://pacotes.<domínio-da-plataforma>/" }
  4. Coloque o shell e o estilo. O mesmo HTML vale em qualquer framework (seção 3).
  5. Garanta a qualidade. bun check, a checagem de tipos do framework, os testes e a acessibilidade passam no CI.
  6. Publique a imagem e peça a rota. A imagem vai para a homologação integrada. A rota no gateway só é criada uma vez; depois, cada empresa publica no seu ritmo.

3 · O que é comum

Tudo o que se repete vai em pacote no Verdaccio

Os apps são independentes, mas não começam do zero. O que precisa ser igual em todos fica em pacotes @fapesb/*, publicados num registry privado e neutro, o Verdaccio. Os pacotes são escritos para funcionar em qualquer framework. Para código comum entre zonas em repositórios separados, o Next indica justamente "public or private NPM packages".

Clique num ramo para recolher ou expandir. As cores indicam a empresa dona de cada pacote.

O cabeçalho comum: Web Components, para servir a todos

O @fapesb/shell traz o cabeçalho, o menu, o rodapé, o botão de login e o aviso de cookies como Web Components, escritos em Lit (TypeScript). É um padrão do navegador: funciona igual em Vue, React e Angular. O React 19 "adds full support for custom elements" (React). O Angular e o Vue também consomem e produzem custom elements (Angular Elements, Vue e Web Components). Escolhemos Lit, e não Vue, para o shell: assim nenhum framework fica no centro, e o Vue cobraria "~16kb" de runtime em cada app que não usa Vue.

<!-- igual em Nuxt, Next e Angular -->
<script type="module" src="/_plataforma/shell/v1/fapesb-shell.js"></script>

<fapesb-cabecalho modulo="contratacao"></fapesb-cabecalho>
<main> … telas do seu módulo … </main>
<fapesb-rodape></fapesb-rodape>
FrameworkO que avisar ao framework
Nuxt (Vue)vue.compilerOptions.isCustomElement: tag => tag.startsWith('fapesb-') || tag.startsWith('br-')
Next (React 19)nada: usa direto. Os tipos vêm de @fapesb/shell/react
Angularschemas: [CUSTOM_ELEMENTS_SCHEMA] no componente
Por que o shell é carregado do gateway, e não instalado em cada app? Para os quatro módulos mostrarem sempre o mesmo cabeçalho. Correções da linha v1 chegam a todos de uma vez. Uma mudança que quebra o shell vira v2, num endereço novo, com RFC e prazo para cada módulo migrar. O pacote npm @fapesb/shell continua existindo, para tipos, testes e desenvolvimento local.

O Verdaccio: cada um no seu Git, pacotes num lugar só

Cada empresa trabalha no seu GitHub ou GitLab. Os pacotes vão para o Verdaccio, que é neutro, gratuito (MIT) e roda em Node 24. O GitHub Packages e o registry do GitLab exigiriam conta de todos na mesma plataforma. A escolha atende ao pedido de "soluções não proprietárias, que não necessitem de aquisições" R1 p.53 · Anexo 3 §1.1(ii).

# config.yaml do Verdaccio — quem lê e quem publica
packages:
  '@fapesb/shell':      { access: $authenticated, publish: zfuture }
  '@fapesb/estilo':     { access: $authenticated, publish: zfuture }
  '@fapesb/contratos':  { access: $authenticated, publish: ci-contratos }
  '@fapesb/base':       { access: $authenticated, publish: [dono-base] }
  '@fapesb/widgets-*':  { access: $authenticated, publish: [zfuture, myappnow, mtm] }
  '**':                 { access: $all, proxy: npmjs }   # o resto vem do npm público, com cache
uplinks:
  npmjs: { url: https://registry.npmjs.org/ }

Widgets entre módulos (ex.: o status do instrumento dentro da tela de submissão) também podem virar Web Components em pacote. Mas a regra é usar pouco. Fowler recomenda que os módulos se comuniquem "as little as possible"; na maioria das vezes, um link para o outro módulo resolve.

4 · Governança

Autonomia dentro do módulo, acordo nas fronteiras

O que só afeta o seu módulo, a sua empresa decide, inclusive o framework, dentro da lista comum. O que afeta outra empresa passa pelo Comitê de Arquitetura, com uma pessoa de cada empresa.

Fronteira · obrigatória

Keycloak, APIs e dados entre sistemas, catálogo de 38 blocos, chaves de ligação, status, ambientes, rotas do gateway, login, @fapesb/shell. Muda só com quórum 4 de 4.

Base comum · por ADR

TypeScript, Node 24 + Bun, frameworks permitidos (Nuxt, Next, Angular), Sass + DSGov, PostgreSQL com um banco por módulo, nomes e URLs, metodologia.

Interno · a dona decide

Framework do módulo (dentro da lista), organização do código, telas, modelo de IA, regras de negócio próprias.

Quando a mudança vai ao comitê? Basta um critério

#A mudança…Exemplo
A1altera API consumida por outra empresamudar o formato do edital enviado à prestação de contas
A2altera dado enviado ou chave de ligaçãotrocar o número do pedido por um ID interno
A3altera o catálogo de 38 blocosenviar um campo novo no bloco 3
A4altera o Keycloak (Realm, perfis, claims, sessão)pedir um perfil transversal novo
A5renomeia ou remove perfil que outro sistema lêrenomear "solicitante"
A6cria integração ou muda o tipo delapassar a enviar em lote noturno
A7altera status compartilhadostatus novo do monitoramento
A8altera disponibilidade, volume ou prazomanutenção da API em horário útil
A9altera dado pessoal que trafega (LGPD) R1 p.68 · §6.2.33.1enviar dados da equipe que hoje não vão
A10altera a experiência comum (login, sessão, shell)cabeçalho próprio num módulo
A11altera ambiente, rota do gateway ou credencial compartilhadosmudar o prefixo /contratacao
A12sai da base comumadotar um framework fora da lista, ou MongoDB

O caminho de uma mudança

Prazo total: até 5 dias úteis. Emergência: corrige primeiro e abre RFC retroativa em 48 h.

Comitê

1 titular + 1 suplente por empresa. Decisão padrão: consenso silencioso em 3 dias úteis. Reunião só quando há objeção.

Coordenador técnico

Indicado pela FAPESB, sem vínculo com as empresas; só vota para desempatar. O edital prevê esse interlocutor: grupos "que interagirão diretamente com a FAPESB e com as empresas" R1 p.31 · §22.6.

Limite do comitê

Não muda escopo de contrato nem decide negócio. Mudança que afeta o mérito técnico vai à FAPESB e só é implementada "após a aprovação formal" R1 p.31 · §22.3.

5 · Identidade

Um login para tudo, em qualquer framework

A MTM configura o Keycloak da FAPESB (Realm FAPESB). Cada app de módulo é um client dele. Quem já entrou num módulo passa direto pelo Keycloak ao abrir outro: o login é um só, mesmo com frameworks diferentes.

No passo 3, quem já tem sessão nem vê a tela de login: o Keycloak devolve o código na hora.

Obrigações de cada módulo

  • Login e logout só pelo Keycloak (OpenID Connect), com client próprio.
  • Tratar o batimento: Conferido entra com perfis; Fora da base entra sem perfil; Não se aplica é servidor.
  • Atribuir os perfis do próprio client pela Admin API.
  • Fazer os controles da FAPESB, como a restrição de horário.

Na prática

  • O botão de login vem pronto no <fapesb-login>.
  • O servidor do app (Nuxt, Next ou Angular SSR) troca o código por token e guarda a sessão em cookie HttpOnly.
  • As APIs validam o token com o @fapesb/base (biblioteca jose).
  • Login gov.br, se a FAPESB quiser, entra como federação no Keycloak, sem mexer nos módulos.

Fundamento: as soluções devem "observar os requisitos de segurança, proteção de dados e conformidade tecnológica" R2 p.5-6 · §4.4.

6 · Integração

Contrato antes de código

Módulos de empresas diferentes conversam só por API, com JSON. O contrato é aprovado antes da implementação, e nenhum módulo acessa o banco de outro. O edital pede "Arquitetura baseada em microsserviços e integração via API RESTful" R1 p.57 · Anexo 3 §2.2.

RegraPadrão
Chaves de ligaçãoCPF (só dígitos), código do edital, número do pedido ou do instrumento, como emitidos pela origem
Versãona URL: /api/<modulo>/v1/; quebrar o contrato cria v2 (critério A1)
Errorecusa com descrição no formato RFC 9457 (application/problem+json) e código estável
Rastreiocabeçalho X-Correlation-Id em toda chamada, registrado nos dois lados
Datas e dinheiroISO 8601 em UTC; valores em texto decimal ("1500000.00"), nunca número de ponto flutuante
Eventosoutbox na mesma transação + webhook assinado no formato CloudEvents (ex.: submissao.proposta.aprovada)
// Recusa com descrição: o sistema de origem corrige e reenvia
{
  "type": "https://plataforma.fapesb.ba.gov.br/erros/prestacao/campo-fora-do-catalogo",
  "title": "Campo não previsto no catálogo",
  "status": 422,
  "detail": "O bloco 3 não aceita o campo 'patente_depositada'. Atualize o catálogo por RFC (A3).",
  "codigo": "PRESTACAO_BLOCO_CAMPO_FORA_DO_CATALOGO",
  "correlation_id": "01JC..."
}

7 · Identidade visual

A cara do governo, em Sass, nos três frameworks

Usamos o Padrão Digital de Governo (DSGov). Ele é escrito em Sass (SCSS), sem Bootstrap nem Tailwind, e Nuxt, Next e Angular compilam Sass nativamente. Por isso todo estilo da plataforma é Sass. A acessibilidade é exigência do edital: "Compatibilidade com padrões de acessibilidade e usabilidade institucional (ex: e-MAG)" R1 p.58 · Anexo 3 §2.2.

Camadas, de baixo para cima

  1. @govbr-ds/core 3.7: tokens, grade, foco acessível, fonte Rawline.
  2. Componentes br-* do DSGov, com o wrapper do seu framework (2.6).
  3. @fapesb/estilo: ponte Sass para o DSGov e a marca FAPESB + Governo da Bahia.
  4. @fapesb/shell: cabeçalho, menu, rodapé e login, iguais em todos.
  5. As telas do seu módulo, com classes BEM e prefixo do módulo.

Tokens principais

  • Primária #1351B4 · sucesso #168821 · alerta #FFCD07 · erro #E52207
  • Espaço em base 8 px: var(--spacing-scale-2x) · raios de 4, 8 e 16 px
  • Não usamos a barra nem a marca do governo federal: a FAPESB é estadual.

Como se escreve um componente (vale para os três frameworks)

@use "@fapesb/estilo" as govbr;           // ponte para os mixins e funções do DSGov

.contratacao-cartao {
  padding: var(--spacing-scale-2x);          // sempre token, nunca valor solto
  font-size: var(--font-size-scale-up-01);
  border: var(--surface-width-sm) solid var(--border-color);

  &__titulo { font-weight: var(--font-weight-semi-bold); }
  &:focus-visible { @include govbr.focus; }     // foco acessível do próprio DSGov
}

Esse SCSS entra num <style lang="scss" scoped> no Vue, num .module.scss no Next e no styleUrl de um componente Angular. Foi testado com o DSGov 3.7.0 e o Sass 1.108.1. O Stylelint 17 com stylelint-config-standard-scss barra cor hexadecimal solta.

8 · Stack e banco

TypeScript em primeiro lugar, framework de front à escolha

O edital diz que Python é a "principal linguagem para IA e NLP" e pede "Node.js e Vue.js/React.js para frontend" R1 p.57 · Anexo 3 §2.2. O resto é TypeScript, de ponta a ponta.

CamadaPadrãoPor quê
FrontNuxt (Vue), Next (React) ou Angular, à escolha de cada empresa; a Z Future usa Nuxtcada time no que domina; um app por rota
RuntimeNode 24 LTS em produçãoroda TypeScript direto (testado com 24.22)
FerramentaBun: bun install, bun test, bun check, bun publishbun check dá os mesmos erros do tsc (testado)
EstiloSass (SCSS) + DSGov + @fapesb/estilomesma linguagem do design system
APIsFastify 5 + Zod; Drizzle no banco; pg-boss para filastipo e validação de uma só fonte
IA e NLPPython 3.12 + FastAPI; MLflow para versões de modelo"DVC ou MLFlow" R1 p.58
BancoPostgreSQL 18, um banco por módulo, leitura e escrita"PostgreSQL (preferencial)" R1 p.57
BackuppgBackRest: completo semanal, diferencial diário, WAL contínuo; restauração testada todo mêscada módulo tem um banco só: o backup é a proteção

Um banco por módulo, leitura e escrita no mesmo lugar

Z FutureMyappnowMTMEmpresa D
Cada módulo tem o seu banco e o seu usuário, e lê e escreve no mesmo endereço. Nenhum módulo acessa o banco de outro: o que precisa ser compartilhado passa pela API (seção 6).

Por que tem de ser o PostgreSQL 18

  • Dura o projeto inteiro. O 18 tem suporte até 14/11/2030; o 17, só até 08/11/2029 (política de versões). Começar no 17 obrigaria a migrar de versão no meio da manutenção da FAPESB.
  • uuidv7() nativo. O nosso padrão de chave é UUID v7. No 18, o próprio banco gera, igual para as quatro empresas e qualquer framework (docs).
  • Leitura mais rápida. O novo I/O assíncrono chega a "up to 3x" em certos cenários.
  • Integridade de fábrica. Bancos criados no 18 vêm com checksums de página ligados, que detectam corrupção silenciosa no disco.
  • Atualizações futuras mais suaves. O pg_upgrade passa a manter as estatísticas do planejador (anúncio do 18).
// tsconfig.json base — testado com bun check e Node 24
{ "compilerOptions": {
    "target": "ES2024", "module": "NodeNext", "moduleResolution": "NodeNext",
    "strict": true, "noUncheckedIndexedAccess": true, "exactOptionalPropertyTypes": true,
    "verbatimModuleSyntax": true, "erasableSyntaxOnly": true,   // sem enum: o Node 24 executa o .ts direto
    "allowImportingTsExtensions": true, "noEmit": true } }
// vale para APIs e pacotes; cada framework de front estende o tsconfig dele

9 · Nomes, URLs e slugs

A mesma coisa tem o mesmo nome em todo lugar

Com quatro frameworks, nomes iguais são o que deixa o código legível para quem chegar depois. E quem chega depois é a FAPESB, que recebe o código R1 p.58 · Anexo 3 §2.3.2.

O quêPadrãoExemplo
Idiomadomínio em português, sem acento nem ç; termos técnicos ficam em inglêsproposta, avaliacao, id, status
Repositóriosfapesb-<modulo>-<peca>fapesb-contratacao-web, fapesb-contratacao-api
Pacotes@fapesb/<nome>@fapesb/shell, @fapesb/widgets-contratacao
URLsminúsculas, kebab-case, plural; o 1º nível é o módulo/submissao/editais/chamada-universal-2026
SlugsASCII, até 80 caracteres, não mudam depois de publicados (o antigo responde 301)"Chamada Universal 2026 — Inovação" → chamada-universal-2026-inovacao
API/api/<modulo>/v1/ + recurso no plural; JSON em snake_casePOST /api/submissao/v1/editais/{codigo_edital}/propostas
Bancoum banco por módulo (fapesb_<modulo>); snake_case; tabelas no pluralfapesb_submissao.propostas.numero_pedido
Custom elementsfapesb-* no shell; <modulo>-* nos widgets<contratacao-status-instrumento>
Classes CSSBEM com prefixo do módulosubmissao-formulario__etapa--ativa
Eventos<modulo>.<entidade>.<fato_no_passado>contratacao.instrumento.assinado
Variáveis de ambienteFAPESB_<MODULO>_<NOME>FAPESB_SUBMISSAO_DATABASE_URL
CommitsConventional Commits, em portuguêsfeat(submissao): adiciona enquadramento por CNAE
LogsJSON; proibido logar CPF, token, senha ou conteúdo de proposta{"nivel":"info","modulo":"submissao","correlation_id":"…"}

10 · Metodologia

O mesmo ritmo nas quatro empresas

O edital pede "Princípios da metodologia ágil (Scrum)" e "DevOps e CI/CD com versionamento Git" R1 p.57 · Anexo 3 §2.2. Com quatro empresas e frameworks diferentes, o que evita surpresa é a sprint nas mesmas datas e uma demonstração conjunta a cada duas semanas.

A review conjunta também cumpre a obrigação de "apresentar informes à EPP com o acompanhamento e status da implantação" R1 p.58 · §2.3.4(iv).

Pronto quer dizer

  • CI verde: bun check, checagem do framework, lint, testes, cobertura ≥ 90% no domínio, acessibilidade sem erro.
  • Revisado por outra pessoa; ADR citado se tocou fronteira.
  • Shell e estilo comuns; estilo só com tokens.
  • Contrato e eventos atualizados; migração reversível; nenhum dado pessoal em log.

Fluxo de código

  • Trunk-based: branch de até 2 dias, PR pequeno (≈ 400 linhas), main sempre pronta.
  • Conventional Commits e SemVer: o CHANGELOG sai dos commits.
  • ADR para cada decisão que cruza módulos; C4 para os diagramas.
  • Defeito entre módulos: issue no módulo suspeito, com o X-Correlation-Id.

Princípios de código: o básico bem feito

PrincípioAqui significaComo se verifica
KISSa solução mais simples que atende a históriarevisão: "dá para fazer com menos?"
YAGNIsó o que está na sprint; pacote, widget ou serviço novo só por RFCrevisão; RFC
DRY com moderaçãoregra de negócio num lugar só; repetiu 3 vezes, extrairevisão
SOLID: S e Duma responsabilidade por módulo e função; Keycloak, SEI, LLM e banco atrás de uma interfacetestes sem rede
Clean Code essencialnomes do glossário, funções curtas, sem código morto, erro nunca engolidolint de complexidade (≤ 10)
Pastas por assuntopropostas/, não controllers/ e services/modelo de projeto

11 · Para decidir

Decisões e pendências

Propostas para o comitê. Cada uma vira um ADR depois de aprovada.

#DecisãoPropostaFundamento
D1Governançacomitê das 4 empresas, quórum 4/4, consenso silencioso em 3 dias úteisR1 p.31 · §22.6
D2LoginKeycloak da FAPESB (MTM); um client por módulo; nada de login próprioR2 p.5-6 · §4.4
D3IntegraçãoOpenAPI antes do código, RFC 9457, versão na URL, PactR1 p.57 · Anexo 3 §2.2
D4VisualDSGov + Sass; @fapesb/shell em Web Components e @fapesb/estiloR1 p.58 · Anexo 3 §2.2
D5LinguagemTypeScript primeiro; Python só para IAR1 p.57
D6FerramentasNode 24 LTS + Bun (bun check)R1 p.57
D7Montagem do frontum app por módulo, por rota, atrás de um gateway Nginx; framework à escolha entre Nuxt, Next e AngularR1 p.57 · R2 p.73 · Anexo 3 §2.3
D8BancoPostgreSQL 18, um banco por módulo, leitura e escrita; backup com pgBackRestR1 p.57
D9Nomesrepositórios, URLs, slugs, API, banco e código num padrão sóR1 p.58 · §2.3.2
D10MétodoScrum sincronizado, trunk-based, Conventional Commits, ADR, C4R1 p.57
D11Pacotescada empresa no seu Git; o comum em pacotes @fapesb/* no VerdaccioR1 p.53 · §1.1(ii)
D12Aceite da FAPESBofício conjunto pedindo aprovação da base comum antes de implementarR1 p.31 · §22.3 · R1 p.65 · §6.2.2

Pendências que precisam de dono

Imediato

  • Coordenador técnico indicado pela FAPESB
  • ADR-0001: Keycloak (MTM)
  • Escopo da Empresa D
  • Framework de cada empresa

Em até 3 semanas

  • Diagramas C1 e C2 de cada módulo
  • Padrão de integração e catálogo de 38 blocos como contrato
  • Verdaccio, gateway, @fapesb/shell v1 e os 3 modelos de projeto
  • Dono do gateway e do portal

Antes de integrar

  • Modelo comum de orçamento (3 módulos)
  • Evento de projetos "aprovados e finalizados" R1 p.50 · §2.2.1
  • Integração com o SEI
  • Homologação integrada; onde rodam os bancos
Atenção à aprovação da FAPESB Alterações "apta[s] a impactar o mérito técnico" do projeto só podem ser implementadas "após a aprovação formal e motivada da Entidade" R1 p.31 · §22.3. A base comum (stack, montagem, banco) precisa desse aceite antes de entrar no código.

Fontes

12 · Glossário

Os termos deste guia, num lugar só

Uma explicação curta de cada termo técnico usado aqui, com um link para a referência oficial.

12-Factor
Doze regras para apps que rodam bem em contêiner: configuração por variável de ambiente, logs na saída padrão, o mesmo artefato em todo ambiente. 12factor.net (PT)
ADR
Registro de decisão de arquitetura: uma página com o contexto, a decisão e as consequências. Toda decisão que cruza módulos vira um ADR. MADR
Angular
Framework de front do Google. Uma das três opções para o app de um módulo. angular.dev
API REST
Forma de um sistema oferecer dados a outro por HTTP, com URLs para cada recurso e respostas em JSON. RFC 9457 (erros)
axe
Ferramenta que verifica acessibilidade automaticamente. Roda junto com o Playwright no CI. Playwright + axe
BEM
Convenção de nomes de classe CSS: bloco__elemento--modificador. Evita que o estilo de um módulo afete outro. getbem.com
Bun
Ferramenta JavaScript/TypeScript que instala pacotes, roda testes, confere tipos (bun check) e publica pacotes. Em produção, quem roda é o Node 24. bun.sh/docs
C4
Modelo de diagramas em níveis: C1 (sistemas), C2 (contêineres), C3 (componentes). As RFCs usam C2 e C3. c4model.com
CI / CD
Integração e entrega contínuas: a cada mudança, o servidor de build roda testes e checagens e, se tudo passar, publica.
CloudEvents
Formato padrão para descrever um evento (o que aconteceu, quando, onde) entre sistemas. cloudevents.io
Contêiner (Docker)
Pacote executável de um programa com tudo de que ele precisa para rodar. Cada app, API e banco de módulo roda num contêiner nos servidores. docs.docker.com
Conventional Commits
Padrão de mensagem de commit (feat:, fix:, chore:) que permite gerar o histórico de mudanças automaticamente. conventionalcommits.org (PT)
Custom element / Web Component
Componente HTML criado com padrões do próprio navegador. Funciona igual em Vue, React e Angular; por isso o cabeçalho comum é feito assim. MDN (PT)
Drizzle
Biblioteca TypeScript para acessar o PostgreSQL com tipos e gerar migrações em SQL. orm.drizzle.team
DSGov
Padrão Digital de Governo: o design system do governo federal (cores, fontes, componentes acessíveis), escrito em Sass. gov.br/ds · Web Components do DSGov
e-MAG / WCAG
Modelos de acessibilidade: o e-MAG é o brasileiro, a WCAG é a referência internacional. O nível AA é critério de aceite. e-MAG · WCAG 2.2
FastAPI
Framework Python para APIs. Usado só no serviço de IA. tutorial (PT)
Fastify
Framework Node para APIs, rápido e com validação por schema. Padrão das APIs TypeScript. fastify.dev
Gateway
O servidor (Nginx) que recebe todo o tráfego do domínio e encaminha cada prefixo de URL para o app do módulo certo. Next Multi-Zones
JWKS / token
O token é o comprovante de login que o Keycloak entrega. O JWKS é o conjunto de chaves públicas que as APIs usam para conferir se o token é verdadeiro.
Keycloak
Servidor de login da FAPESB. Guarda as contas e os perfis; cada módulo é um client dele. proteger apps com OIDC
LGPD
Lei Geral de Proteção de Dados (Lei 13.709). Por ela, CPF e outros dados pessoais não vão para logs e só trafegam quando necessário. planalto.gov.br
Lit
Biblioteca pequena para criar Web Components em TypeScript. Usada no @fapesb/shell para não depender de nenhum framework. lit.dev
Locust
Ferramenta em Python para teste de carga. Gera o relatório de carga exigido pelo edital. docs.locust.io
Micro-frontend
Dividir o front de um produto grande em partes de times diferentes. Aqui, cada módulo é um app próprio atrás do gateway. Cam Jackson, martinfowler.com · micro-frontends.org
MLflow
Ferramenta para registrar versões de modelos de IA, métricas e artefatos. mlflow.org
Monorepo
Um repositório com o código de vários projetos. Não usamos: cada empresa tem os próprios repositórios.
Next
Framework de front sobre React. Uma das três opções para o app de um módulo. nextjs.org · React (PT)
Node 24 LTS
O motor que roda JavaScript e TypeScript no servidor, em produção. LTS significa versão com suporte longo. rodar TypeScript direto
Nuxt
Framework de front sobre Vue. É o que a Z Future usa. nuxt.com · Vue (PT)
OIDC
OpenID Connect: o protocolo de login que o Keycloak fala com os módulos.
OpenAPI
Formato para descrever uma API (rotas, campos, erros) antes de escrever o código. É o contrato entre as empresas. learn.openapis.org
Outbox
Padrão para não perder evento: o evento é gravado na mesma transação do dado e enviado depois por um processo separado. microservices.io
OWASP Top 10 / ASVS
Listas de referência de segurança de aplicações web. Base do relatório de vulnerabilidades. Top 10 · ASVS
Pacote npm / escopo
Código empacotado e versionado que outros projetos instalam. O escopo @fapesb agrupa os nossos pacotes. pacotes · escopos
Pact
Teste de contrato: o consumidor descreve o que espera da API, e o provedor prova que entrega. docs.pact.io
pgBackRest
Ferramenta de backup do PostgreSQL, com restauração para qualquer momento (PITR). guia
PostgreSQL 18
O banco de dados da plataforma. Cada módulo tem o seu. tutorial · novidades do 18
RFC (proposta de mudança)
Documento curto que propõe uma mudança que afeta outras empresas, com impacto e diagramas. Vai ao comitê; aprovada, vira ADR.
Sass / SCSS
Linguagem que estende o CSS com variáveis, funções e mixins. O DSGov é escrito nela, e todo o estilo da plataforma também. sass-lang.com
Scrum
Forma de trabalho em ciclos curtos (sprints), com planejamento, reunião diária, demonstração e retrospectiva. Guia do Scrum (PT)
SemVer
Versionamento semântico: MAJOR.MINOR.PATCH. Mudar o primeiro número significa que algo deixou de ser compatível. semver.org (PT)
Shell
O cabeçalho, o menu, o rodapé e o botão de login comuns a todos os módulos (@fapesb/shell).
Slug
O trecho legível de uma URL gerado do título, como chamada-universal-2026.
SSR
Renderização no servidor: a página já chega pronta do servidor, o que ajuda velocidade e buscadores.
Trunk-based development
Forma de trabalhar com branches curtas que voltam rápido para a main, que fica sempre pronta para publicar. trunkbaseddevelopment.com
TypeScript
JavaScript com tipos. É a linguagem principal da plataforma. Handbook
Verdaccio
Registry npm privado onde ficam os pacotes @fapesb. Neutro: funciona com quem usa GitHub ou GitLab. verdaccio.org
Zod
Biblioteca TypeScript que valida dados e gera o tipo a partir da mesma definição. zod.dev