Appearance
Documentação Técnica (este site)
Este site é gerado pelo apps/docs-tec usando VitePress com suporte a diagramas Mermaid.
A referência automática de tipos agora vive em um artefato separado, apps/docs-tipos, voltado exclusivamente ao uso local de desenvolvimento.
Como rodar localmente
bash
# Instalar dependências (se ainda não fez)
pnpm install
# Dev server na porta 3011
pnpm --filter @fc/docs-tec dev:openComo o conteúdo é organizado
O site usa dois mecanismos de conteúdo:
1 — <!--@include:--> (maioria das páginas)
A diretiva nativa do VitePress inclui o conteúdo de um arquivo externo diretamente. As páginas do site público sempre incluem o README.md do app/package — que é a versão pública sanitizada.
md
<!-- apps/docs-tec/site/pacotes/utils.md -->
# @fc/utils
Pacote base do monorepo com classes e funções de propósito geral. **Não tem dependências internas** — é a raiz do grafo de dependências da Fábrica de Cálculos.
## Módulos
Não há barrel: cada função é um arquivo, e o consumidor importa o arquivo que declara o símbolo pelo subpath `@fc/utils/<módulo>/<arquivo>` (ex.: `@fc/utils/datas/antesDe`). O `exports` do `package.json` publica cada módulo por wildcard (`./datas/*` → `src/datas/*.ts`); importar `@fc/utils` pela raiz não resolve e é barrado pelo linter.
| Módulo | Conteúdo principal |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `datas` | Aritmética de datas: `adicionarDias360`, `diferencaEntreDatas`, `ultimoDiaDoMes`, `entreCompetencias`, `mesmaCompetencia`, e mais de 40 funções para manipulação de datas no contexto previdenciário |
| `numeros` | Arredondamento, truncamento e formatação numérica |
| `strings` | Normalização, limpeza e comparação de strings |
| `predicados` | Funções de verificação de tipo e pertencimento: `tipoNumero`, `tipoString`, `tipoData`, `tipoObjeto`, `ehValorDeDicionario`, etc. |
| `validacao` | Validação de CPF, datas, competências e outros dados de entrada |
| `objetos` | Utilitários para manipulação de objetos e clonagem profunda |
| `vetores` | Operações sobre arrays: agrupamento, ordenação, deduplcação |
| `enums` | Utilitários de enumeração |
| `url` | Manipulação agnóstica de URLs e caminhos: `juntarUrl`, `normalizarCaminhoUrl`, `extrairHostname`, `ehHostLocal` |
| `http` | Requisições JSON resilientes e interpretação do tempo de espera informado por serviços HTTP |
| `etc` | Funções auxiliares diversas |
## Antes de criar uma função nova
Verifique primeiro se já existe uma função equivalente neste pacote ou em `@fc/comum`.
Use `@fc/utils` para funções compartilháveis que sejam agnósticas em relação ao domínio da Fábrica de Cálculos: datas, números, strings, predicados, objetos, URLs, serialização, validação genérica e infraestrutura técnica. Se a função souber de calculadoras, apps, contratos de API, mensagens do produto ou vocabulário de negócio, o destino provável é `@fc/comum`, não `@fc/utils`.
## Web Workers — `criarWorkerScope`
Todas as apps da Fábrica de Cálculos executam cálculos pesados fora da thread principal usando a infraestrutura de `criarWorkerScope` deste pacote.
```ts
// No arquivo worker (ex: composables/worker/calcular.worker.ts)
import { criarWorkerScope } from '@fc/utils/etc/worker/criarWorkerScope'
criarWorkerScope(async (mensagem) => {
// executa na thread do worker
const resultado = await calcular(mensagem.dados)
return resultado
})O composable de UI obtém o worker via new Worker(new URL('./calcular.worker.ts', import.meta.url), { type: 'module' }) e usa postMessage/onmessage para comunicação assíncrona.
Uso
ts
import { converterStringEmData } from '@fc/utils/datas/converterStringEmData'
import { mesmaCompetencia } from '@fc/utils/datas/mesmaCompetencia'
import { ehValorDeDicionario } from '@fc/utils/predicados/ehValorDeDicionario'
import { tipoNumero } from '@fc/utils/predicados/tipoNumero'
converterStringEmData('01/2024') // Date
mesmaCompetencia(new Date(), outra) // boolean
ehValorDeDicionario(valor, dicionario) // preserva o tipo dos valores
tipoNumero(1) // trueClientes HTTP podem declarar sua própria política de confiabilidade e reutilizar o transporte agnóstico:
ts
import { requisitarJson } from '@fc/utils/http/requisitarJson'
const { resposta, dados } = await requisitarJson(url, {
nomeServico: 'Serviço externo',
politica: {
maximoTentativas: 3,
timeoutTentativaMs: 10_000,
orcamentoTotalMs: 30_000,
atrasoBaseMs: 250,
limiteCorpoBytes: 2 * 1024 * 1024,
},
})Para coordenar uma nova tentativa sem adotar o transporte completo, obterEsperaRetryAfter interpreta o cabeçalho Retry-After em segundos ou data HTTP e devolve o intervalo em milissegundos:
ts
import { obterEsperaRetryAfter } from '@fc/utils/http/obterEsperaRetryAfter'
const esperaMs = obterEsperaRetryAfter(resposta.headers)Instalação (monorepo)
jsonc
// package.json
{ "dependencies": { "@fc/utils": "workspace:*" } }Os packages/ exportam TypeScript puro: o exports do package.json aponta direto para os .ts de src/ — sem step de compilação.
### 2 — Conteúdo curado (páginas de arquitetura, guias, segurança)
Páginas que agregam informação de múltiplas fontes ou contêm diagramas Mermaid têm conteúdo escrito diretamente em `site/`.
### 3 — Visibilidade por frontmatter
Toda página em `site/**/*.md` declara `visibilidade: publico` (ou `interno`) no frontmatter. Páginas com `visibilidade: interno` são excluídas do build de produção, mas aparecem em desenvolvimento com prefixo `[INTERNO]`. Conteúdo realmente sensível (credenciais, schema literal, rotas privadas, headers proprietários) fica nos `CONTEXT.md` internos da raiz, app ou package dono do assunto, **fora do site público**.
O linter `pnpm docs:lint` cobre os dois sites, os READMEs públicos e arquivos textuais publicados. Ele bloqueia CPFs com DV válido, rotas privadas, headers proprietários, credenciais conhecidas, hostnames internos, nomes de configuração de implantação e caminhos operacionais, entre outros detalhes que não pertencem à superfície pública.
Os arquivos visuais publicados também têm hash, origem e data de revisão registrados em um inventário. Um arquivo novo ou alterado exige aprovação humana antes de o inventário ser atualizado; OCR pode auxiliar a conferência, mas não substitui essa revisão.
## Mapa seção → fonte
| Seção do site | Fonte de verdade |
| ----------------------------------- | --------------------------------------------- |
| `/visao-geral/` | Curado |
| `/arquitetura/` | Curado + diagramas Mermaid |
| `/calculadoras/prev-tc` | `apps/prev-tc/README.md` |
| `/calculadoras/prev-rvt` | `apps/prev-rvt/README.md` |
| `/calculadoras/prev-atrasados` | `apps/prev-atrasados/README.md` |
| `/calculadoras/prev-rpps` | `apps/prev-rpps/README.md` |
| `/apis/prev-api` | `apps/prev-api/README.md` |
| `/apis/rmi-api` | `apps/rmi-api/README.md` |
| `/apis/backoffice` | `apps/backoffice/README.md` |
| `/pacotes/utils` | `packages/utils/README.md` |
| `/pacotes/comum` | `packages/comum/README.md` |
| `/pacotes/indices` | `packages/indices/README.md` |
| `/pacotes/calculos-judiciais` | `packages/calculos-judiciais/README.md` |
| `/pacotes/calculos-previdenciarios` | `packages/calculos-previdenciarios/README.md` |
| `/pacotes/calculos-rpps` | `packages/calculos-rpps/README.md` |
| `/pacotes/parsers` | `packages/parsers/README.md` |
| `/pacotes/cliente-sgs` | `packages/cliente-sgs/README.md` |
| `/pacotes/cliente-sidra` | `packages/cliente-sidra/README.md` |
| `/pacotes/swagger-nuxt-module` | `packages/swagger-nuxt-module/README.md` |
| `/desenvolvimento/nova-camada-nuxt` | `apps/base/README.md` |
## Referência TypeScript local
A documentação automática de tipos é gerada pelo app separado `apps/docs-tipos`. Ela não faz parte do `docs-tec` público e não entra no pipeline de publicação.
```bash
# Gerar HTML do TypeDoc
pnpm --filter @fc/docs-tipos generate
# Rodar em modo local com watch
pnpm --filter @fc/docs-tipos devBuild completo
bash
pnpm --filter @fc/docs-tec buildAdicionando uma nova seção
- Criar o arquivo
.mdemapps/docs-tec/site/<secao>/nome.mdcom frontmattervisibilidade: publico. - Se o conteúdo vem de um README externo: garantir que o
README.mddo app ou package esteja sanitizado (sem credenciais, rotas privadas ou detalhes operacionais) e adicionar a diretiva@includeapontando para ele (ex.:../../../../apps/prev-tc/README.md). Nunca incluir oCONTEXT.md(interno). - Adicionar a entrada correspondente no sidebar em
apps/docs-tec/site/.vitepress/config.ts. - Rodar
pnpm docs:lintepnpm --filter @fc/docs-tec devantes de abrir PR.