34 KiB
PROGRESS.md — Histórico e Estado Atual do VentoApp
Arquivo de continuidade. Este documento é o ponto de partida quando você retomar o trabalho em um novo terminal/sessão. Ele contém:
- Estado exato em que o projeto está HOJE
- Tudo o que foi entregue (com paths)
- Comandos para validar o estado
- Roadmap priorizado das próximas melhorias
- Convenções estabelecidas que devem ser mantidas
📊 Estado atual
| Item | Valor |
|---|---|
| Data da última atualização | 2026-07-07 |
| Marcos concluídos | 8 / 8 (plano completo) + M9.1 ✅ + M9.2 ✅ + M9.3 ✅ + M9.4 ✅ + M9.5 ✅ + M9.6 ✅ + M9.7 ✅ + M9.8 ✅ + M9.9 ✅ + M9.10 ✅ + M9.13 ✅ |
| Cobertura NBR 6123:2023 | 100% das 11 seções + 3 anexos |
| Linhas de código TS/TSX | ~7.400 |
Arquivos .ts/.tsx no src/ |
110 |
| Páginas (rotas) | 10 |
| Módulos Strategy | 7 |
| Tabelas da norma implementadas | 36 / 36 + 3 anexos (auditadas M9.1) |
| Testes Vitest | 310 passando / 310 totais |
| Build de produção | ✅ passa (2645 módulos) |
| Lint (oxlint) | ✅ 0 erros |
| Persistência local | ✅ IndexedDB (Dexie-style) |
| Tema dark/light | ✅ ThemeProvider com 3 modos |
✅ O que foi entregue (Marcos 1–8)
Marco 1 — Motor matemático refatorado
Status: ✅ Concluído Entregas:
app/src/lib/nbr-tables/table-1.ts— Parâmetros meteorológicos (b, p, Fᵣ)app/src/lib/nbr-tables/table-2.ts— Fator de rajadaapp/src/lib/nbr-tables/table-3.ts— Fator S₂ (interpolação log-linear)app/src/lib/nbr-tables/table-4.ts— Fator S₃ mínimo (5 grupos)app/src/lib/nbr-tables/table-5.ts— z_g e z₀ por categoriaapp/src/lib/nbr-tables/table-a.ts— S₂ normalizado (Anexo A)app/src/lib/nbr-tables/table-b.ts— S₃ por Pₘ e vida útil (Anexo B)app/src/lib/bilinear-interp.ts— Interpolação bilinear (sec. 3.2)app/src/lib/log-interp.ts— Interpolação log-linear + linearapp/src/lib/wind-direction.ts— Mudança de rugosidade (sec. 5.5)app/src/lib/wind-kernel.ts— Refatorado para consumir tabelas
Marco 2 — Pressão interna + Vizinhança
Status: ✅ Concluído Entregas:
app/src/lib/internal-pressure.ts— Cpi simplificado (6.3.2) + detalhado (6.3.3)app/src/lib/neighborhood.ts— Fator fᵥ (sec. 6.4)app/src/lib/nbr-tables/stations.ts— 49 estações Anexo Capp/src/lib/stations-lookup.ts— Busca por nome/IBGEapp/src/store/galpaoStore.ts— Adicionado Cpi, ratio, permeabilityCase- UI Galpão: 4 abas (Geometria / NBR / Cpi / Local)
Marco 3 — Edificações paralelepipédicas completas
Status: ✅ Concluído Entregas:
app/src/lib/nbr-tables/table-6.ts— Cpe paredes (A, B, C, D)app/src/lib/nbr-tables/table-7.ts— Cpe telhados duas águas (E–J)app/src/lib/nbr-tables/table-8.ts— Cpe telhados uma águaapp/src/lib/nbr-tables/table-9.ts— Cpe telhados duas águas com calhaapp/src/lib/nbr-tables/table-10.ts— Cpe telhados múltiplos simétricosapp/src/lib/nbr-tables/table-11.ts— Cpe telhados múltiplos assimétricosapp/src/lib/nbr-tables/table-12.ts— Cpe telhados com água verticalapp/src/lib/coefficients.ts— Interface unificadaapp/src/lib/excentricity.ts— Sec. 6.1.4 (eₐ, e_b)app/src/lib/friction.ts— Sec. 6.1.5 (força de atrito)app/src/lib/drag.ts— Ca baixa/alta turbulência (Figs 4-5) + requisitosapp/src/components/Warehouse3D.tsx— Refeito com zonas A-J coloridas independentemente
Marco 4 — Superfícies curvas
Status: ✅ Concluído Entregas:
app/src/lib/nbr-tables/table-13.ts— Cpe cilindros (Re + h/d + ângulo)app/src/lib/nbr-tables/table-14.ts— Ca seção constante (15+ seções)app/src/lib/nbr-tables/table-15-17.ts— Abóbadas (baixa turbulência)app/src/lib/nbr-tables/table-18-20.ts— Abóbadas (séries 51, 52)app/src/lib/nbr-tables/table-21.ts— Cúpulas sobre terrenoapp/src/lib/nbr-tables/table-22.ts— Cúpulas sobre parede cilíndricaapp/src/lib/modules/cylinder.ts,vault.ts,dome.ts— Strategyapp/src/components/three/Cylinder3D.tsx,Vault3D.tsx,Dome3D.tsxapp/src/pages/CylinderModule.tsx,VaultModule.tsx,DomeModule.tsx
Marco 5 — Muros, placas, coberturas isoladas, barras
Status: ✅ Concluído Entregas:
app/src/lib/nbr-tables/table-23.ts— Cf muros/placasapp/src/lib/nbr-tables/table-24-25.ts— Coberturas isoladas (uma e duas águas)app/src/lib/nbr-tables/table-26.ts— Cx, Cy barras faces planasapp/src/lib/nbr-tables/table-27.ts— Ca barras circulares (Re + regime)app/src/lib/nbr-tables/table-28.ts(via table-26/27) — Fator Kapp/src/lib/nbr-tables/table-29.ts— Cf fios/cabosapp/src/lib/nbr-tables/table-30.ts— Componentes em faces de torreapp/src/lib/modules/truss.ts— Reticulados isolados/múltiplosapp/src/pages/SignModule.tsx,IsolatedRoofModule.tsx,BarSelectorModule.tsx
Marco 6 — Torres + Pontes
Status: ✅ Concluído Entregas:
app/src/lib/modules/tower.ts— Torres quadradas e triangularesapp/src/lib/modules/bridge.ts— Pse, Cx/Cz, flutter, galopeapp/src/lib/nbr-tables/table-35.ts— Parâmetros b, p para pontes + amortecimento (Tab. 36)app/src/pages/BridgeModule.tsx
Marco 7 — Dinâmica + Vórtices + Conforto
Status: ✅ Concluído Entregas:
app/src/lib/nbr-tables/table-31.ts— Parâmetros dinâmicos (γ, ξ)app/src/lib/nbr-tables/table-32.ts— Expoente p, bₘ dinâmicos + Vp, ζapp/src/lib/nbr-tables/table-33.ts— Strouhal (St) + Scruton + Vcrapp/src/lib/comfort.ts— a_lim ISO 10137app/src/lib/modules/dynamics.ts— Re-export consolidadoapp/src/pages/DynamicsModule.tsx— 3 abas (Edifício / Vórtices / Conforto)
Marco 8 — UX, dados, testes
Status: ✅ Concluído Entregas:
app/src/lib/storage.ts— Persistência IndexedDB (CRUD de projetos)app/src/lib/hooks/useProjects.ts— Hook React para projetosapp/src/lib/theme.tsx— ThemeProvider (light/dark/system)app/src/lib/i18n.ts— Strings pt-BR/en-USapp/src/pages/SettingsModule.tsx— Tema + projetos + estadoapp/vitest.config.ts— Configuração Vitestapp/src/lib/__tests__/— 5 suites de testes (38 testes)app/index.html— Atualizado (lang, title, description)app/README.md— Documentação completaAGENTS.md— Guia para IAs continuarem
Marco 9.2 — Cargas lineares (kN/m) para software estrutural
Status: ✅ Concluído (2026-07-07) Escopo: Converter pressões (kN/m²) em cargas distribuídas lineares (kN/m) para software como Ftool, SAP2000, Eberick, TQS. Entregas:
app/src/lib/line-loads.ts— 8 funções:getWindLoadOnRoof(cpe, cpi, q, s, θ)→ kN/m em terça (com cos θ)getWindLoadOnColumn(cpe, cpi, q, spacing)→ kN/m em pilargetPillarBaseReaction(w, h)→ V_base [kN]getPillarBaseMoment(w, h)→ M_base [kN·m]getColumnLinearLoads(...)→ cargas nos 4 pilares (vento 0°/90°)getRoofLinearLoads(...)→ cargas nas terças por zona E/F/G/H/I/JgetAllPillarBaseReactions(...)→ reações nos 4 pilaresgetDragForce(...)→ força de arrasto total + Cₐ efetivo
app/src/components/LinearLoadsTable.tsx— Painel interativo com 3 abas (Pilares / Terças / Reações) + inputs para espaçamento de pórticos/terças.app/src/lib/export-pdf.tsx— Nova seção 5 no PDF com 3 sub-tabelas.app/src/lib/export-csv.ts— Novas seções no CSV.app/src/pages/GalpaoModule.tsx— Layout 3 colunas: controles / 3D / cargas.- Suite de testes nova:
app/src/lib/__tests__/line-loads.test.ts(27 testes). - Total: 110/110 testes passando (era 83/83).
Convenção de sinal:
+= empuxo (pressão empurrando para dentro da estrutura)−= sucção (puxando para fora)
Marco 9.3 — Captura 3D no PDF (screenshot da cena)
Status: ✅ Concluído (2026-07-07) Escopo: Capturar screenshot do canvas R3F e embutir automaticamente na memória de cálculo em PDF. Entregas:
app/src/lib/canvas-capture.ts— Utilitários determinísticos:canvasToDataURL(canvas, format, quality)→ data URLcaptureCanvasImage(canvas, options)→ captura + redimensionamentodownloadImage(dataUrl, filename)→ download diretoestimateDataUrlSizeKB(dataUrl)→ estimativa de tamanhodataURLtoBlob(dataUrl)→ conversão para Blob
app/src/store/captureStore.ts— Zustand store para registro e captura:registerCanvas(canvas)/unregisterCanvas()capture()assíncrono com await- Configuração: targetWidth, format (png/jpeg), jpegQuality
app/src/components/SceneCapturePanel.tsx— Painel UI no estilo GalpaoModule:- Select para formato, Slider para largura/qualidade
- Botão "Capturar cena atual" com estado de loading
- Preview com badge de tamanho + timestamp
- Botões Baixar/Limpar
- 4 viewers 3D registrados (Warehouse3D, Cylinder3D, Vault3D, Dome3D):
- Adicionado
gl={{ preserveDrawingBuffer: true, antialias: true }} onCreated={({ gl }) => registerCanvas(gl.domElement)}
- Adicionado
app/src/lib/export-pdf.tsx— Nova seção 5 (entre Coeficientes e Cargas Lineares) com<Image>do react-pdf + legenda.app/src/pages/GalpaoModule.tsx— Layout 4 colunas (controles / 3D / cargas / captura).- Suite de testes nova:
app/src/lib/__tests__/canvas-capture.test.ts(13 testes). - Total: 123/123 testes passando (era 110/110).
Requisitos técnicos:
preserveDrawingBuffer: trueno contexto WebGL para permitirtoDataURL.Image as PdfImagedo@react-pdf/rendereraceita data URL direto.- Renumeração dinâmica de seções no PDF (5 → 6 quando há captura).
Marco 9.4 — Exportação Ftool (.txt estruturado)
Status: ✅ Concluído (2026-07-07) Escopo: Gerar arquivo texto com nós, barras e cargas lineares no formato de importação do Ftool (software livre de pórticos planos da PUC-Rio, amplamente usado em escritórios brasileiros). Entregas:
app/src/lib/export-ftool.ts— 5 tipos exportados + 4 funções:buildFtoolModel()→ monta o modelo 2D do pórtico (6 nós, 4 barras)serializeFtool(model)→ texto no formato Ftool ASCIIexportGalpaoToFtool()→ dispara download do .txt- Tipos:
FtoolModel,FtoolNode,FtoolMember,FtoolMemberLoad
app/src/components/ExportMenu.tsx— 3º botão "Ftool" (verde esmeralda) na barra de exportação.app/src/components/FtoolExportCard.tsx— Card lateral no GalpãoModule com preview do conteúdo do arquivo + botão de download.app/src/pages/GalpaoModule.tsx— Coluna extra com FtoolExportCard.- Suite de testes nova:
app/src/lib/__tests__/export-ftool.test.ts(26 testes cobrindo modelo, serialização e robustez). - Total: 149/149 testes passando (era 123/123).
Layout do pórtico gerado:
- N1 (0, 0) → N4 (0, h) — coluna esquerda (barlavento)
- N4 (0, h) → N5 (b/2, h+rise) — água esquerda
- N5 (b/2, h+rise) → N6 (b, h) — água direita
- N6 (b, h) → N3 (b, 0) — coluna direita (sotavento)
- Mais 2 nós auxiliares N2 (b/2, h) para carregamento opcional
Convenção Ftool:
- Unidades: kN, m
- Cargas de coluna:
Dir GlobalX(perpendicular à parede) - Cargas de terça:
Dir GlobalY(vertical, no plano do pórtico) - 1 caso de carga nomeado "Vento θ° (q=..., Cpi=...)"
Marco 9.5 — Refatoração TypeScript (eliminar void e as unknown as)
Status: ✅ Concluído (2026-07-07)
Escopo: Limpar padrões TypeScript fracos (void X para silenciar
noUnusedLocals, as unknown as number[] para escapar de checagem
de tipo) e melhorar a robustez dos módulos Strategy.
Entregas:
- Eliminação de
void X: removidos 8 padrõesvoidem 4 arquivos (truss.ts, table-32.ts, table-24-25.ts). - Eliminação de
as unknown as: removidos 26 padrões em 13 arquivos (table-3, 11, 12, 13, 15-17, 18-20, 23, 26, 27, modules/{truss,tower,vault}). - Tipagem forte em vault.ts: substituído
Record<string, number>por interfacesVaultCpeWindPerpendicular/VaultCpeWindParallel(expostos da tabela). - Correção de bugs latentes em interpolação:
bilinear-interp.ts:findBracketagora trata arrays de 1 elemento corretamente (evitaxs[-1]quando length=1).log-interp.ts:findBracketidem.
- Flags TypeScript adicionadas:
noImplicitOverrideemtsconfig.app.json. - Suite de testes nova:
app/src/lib/__tests__/refactoring.test.ts(25 testes cobrindo cylinder, truss, tower, vault, table-32, 33, 26, 24-25, 23, 21, 22). - Total: 174/174 testes passando (era 149/149).
Padrão antes/depois:
// Antes: silent unused + cast duvidoso
const { alphaWind, phi, aeFace, q } = input;
void input;
const grid = { xs: PHI_15 as unknown as number[], ys: [1] as readonly number[], values: [...] };
return bilinearInterp(grid, phiClamped, 1);
// Depois: tipagem explícita + nada desperdiçado
const { barType, phi, aeFace, alphaWind, q } = input;
const grid = { xs: PHI_15, ys: [1] as readonly number[], values: [...] };
return bilinearInterp(grid, phiClamped, 1);
Pendências descobertas (não corrigidas neste marco):
table-18-20.ts: chaves deT18(0.25, 0.5, 1) não casam comFL(0.05, 0.1, 0.2, 0.3, 0.4).table-21.tsetable-22.ts: usamf.toString()masT21/T22têm chaves literais como'1/15'—lookupretornaundefined.- Recomendação: M9.10 ou roadmap futuro para alinhar chaves.
Marco 9.1 — Auditoria de tabelas NBR 6123:2023
Status: ✅ Concluído (2026-07-07) Escopo: Auditar todas as 33 tabelas + 3 anexos contra o PDF oficial Entregas:
- Todos os 33 arquivos
app/src/lib/nbr-tables/table-*.tsestations.tsagora têm cabeçalho comFonte: NBR 6123:2023, p. XXeÚltima auditoria: 2026-07-07. - Correções aplicadas:
- Tabela 4 (S3): Grupo 1 de 1,10 → 1,11 (PDF p. 15).
Grupo 2 de 1,08 → 1,06. Adicionado
vidaUtilAnos(100, 75, 50, 30, 2). - Tabela 35 (pontes): refatorada — era função de altura z, mas a norma define
p e bₘ constantes por categoria. Corrigidos valores:
- I: 0,10 / 1,25 | II: 0,16 / 1,00 | III: 0,20 / 0,85 | IV: 0,25 / 0,68 | V: 0,35 / 0,44
- Tabela 36 (amortecimento de pontes): corrigidos valores discrepantes (Madeira 6,0 → 8,0; Protensão parcial 2,0 → 2,5; Mistas 1,5 → 1,8).
- Stations.ts (Anexo C): altitudes corrigidas (Curitiba 510 → 910; BH 780 → 789; Anápolis 1087 → 1097; Campinas 661 → 648) + coordenadas conferidas.
- Tabela 4 (S3): Grupo 1 de 1,10 → 1,11 (PDF p. 15).
Grupo 2 de 1,08 → 1,06. Adicionado
- Suite de testes nova:
app/src/lib/__tests__/nbr-tables.test.ts(43 testes cobrindo Tabelas 1, 3, 4, 5, 32, 35, 36, Anexo B e Anexo C). - Total: 83/83 testes passando (era 38/38).
Pendências (⚠️ marcadas nos arquivos):
- Tabelas 6, 7, 8, 9, 10, 11, 12: valores simplificados no código; a norma fornece matrizes por h/b × θ × zona que precisam ser expandidas.
- Tabela 13: chaves de indexação usam "0.5/5/25" mas a norma define apenas "h/d=10" e "h/d≥2,5"; precisa reagrupamento.
- Tabela 14: 15+ seções × 7 razões h/ℓ × 6 Reynolds — usar valores pré-computados por combinação específica.
- Tabelas 15–22: revisar valores numéricos por f/b e zonas (1 a 6).
- Tabela A.1, A.2: revisar valores exatos por categoria × intervalo (PDF p. 99–101).
- Tabela B.1: confirmar valores exatos da grade Pₘ × m (PDF p. 104).
- Tabela 31: revisar parâmetros γ, ξ por tipo de estrutura (PDF p. 74).
- Tabela 33: revisar Strouhal por forma da seção.
- Estações: revisar V₀ de cada uma contra Figura 1 oficial.
🔧 Validação rápida do estado atual
cd /root/Apps/windapp/app
# 1. Compilação TS (deve passar sem erros)
./node_modules/.bin/tsc -b
# 2. Testes (deve mostrar 38/38 passing)
./node_modules/.bin/vitest run
# 3. Lint (deve mostrar 0 errors, ~5 warnings cosméticos)
./node_modules/.bin/oxlint
# 4. Build de produção
./node_modules/.bin/vite build
# 5. Dev server
npm run dev
Resultado esperado:
- ✅ tsc: silent (sem output)
- ✅ vitest:
Test Files 5 passed (5) | Tests 38 passed (38) - ✅ oxlint:
Found N warnings and 0 errors - ✅ vite:
✓ built in ~2scomdist/assets/index-*.js ~2.9 MB
🚀 Roadmap priorizado de melhorias (pós-Marco 8)
🔴 Alta prioridade (Melhorias de qualidade técnica)
M9.1 — Refinar valores das tabelas a partir do PDF real (~3 dias)
Status: ✅ Concluído (ver Marco 9.1 acima). Headers de fonte adicionados a todas as 33 tabelas. Correções críticas aplicadas em Tab. 4, Tab. 35, Tab. 36, Stations (Anexo C). Suite de testes +43 casos (83/83 passando). Pendências: ver seção "Pendências" no Marco 9.1. Problema: Os valores das tabelas foram digitados baseados no OCR do PDF. Algumas tabelas (especialmente 14, 18-22) usam aproximações simplificadas. Tarefa:
- Comparar cada tabela em
lib/nbr-tables/*.tscom a norma oficial - Corrigir discrepâncias (especialmente Tab. 14 com 15+ seções × 7 razões h/ℓ)
- Adicionar testes Vitest validando contra exemplos resolvidos do Blessmann
- Adicionar documentação inline apontando a fonte (página da norma)
M9.2 — Cargas lineares (kN/m) para software estrutural (~2 dias)
Status: ✅ Concluído (ver Marco 9.2 acima). 8 funções implementadas em
line-loads.ts. Painel interativo no GalpãoModule. PDF e CSV com seções dedicadas.
27 testes novos (110/110 passando).
M9.3 — Screenshot 3D no PDF (~1 dia)
Status: ✅ Concluído (ver Marco 9.3 acima). 4 viewers 3D registram canvas via Zustand. Painel interativo com Select/Slider/Preview no estilo GalpaoModule. PDF incorpora imagem automaticamente. 13 testes novos (123/123 passando).
🟡 Média prioridade (UX e polimento)
M9.4 — Exportação Ftool (.txt estruturado) (~2 dias)
Status: ✅ Concluído (ver Marco 9.4 acima). Pórtico 2D exportado com 6 nós + 4 barras + 1 caso de carga. 26 testes novos (149/149 passando).
M9.5 — Refatoração TypeScript (~1 dia)
Status: ✅ Concluído (ver Marco 9.5 acima). 8 padrões void + 26 padrões
as unknown as removidos. Bugs latentes em findBracket corrigidos.
Tipagem forte em vault.ts. 25 testes novos (174/174 passando).
M9.6 — Modo de visualização 3D para todas as estruturas (~3 dias)
Status: ✅ Concluído (2026-07-07). 4 novos componentes 3D criados e integrados. Ver Marco 9.6 abaixo.
Marco 9.6 — Visualização 3D para muros / torres / pontes / barras
Status: ✅ Concluído (2026-07-07) Escopo: Cobrir as 4 estruturas restantes (que só tinham SVG 2D) com visualização 3D interativa, vetores de força, e cores por intensidade. Entregas:
app/src/components/three/Sign3D.tsx— muros/placas retangulares: placa colorida por Cf + seta de força no ponto de aplicação + placas de extremidade opcionais (quando ℓ/hₐ < 60).app/src/components/three/Tower3D.tsx— torres reticuladas: geração procedural de barras (montantes + diagonais em X + travessas horizontais) para seção quadrada (4 cantos) ou triangular equilátera (3 cantos); seta de força no topo.app/src/components/three/Bridge3D.tsx— pontes: tabuleiro retangular + 3 pilares (1/3·Lₚ, 1/2·Lₚ, 2/3·Lₚ) + guarda-rodas/barreiras laterais + vetor Cx horizontal (vermelho)- vetor Cz vertical (azul) sobre o tabuleiro.
app/src/components/three/Bar3D.tsx— barras isoladas: cilindro para circular, formas paramétricas (placa, L, T, I, retângulo) para faces planas, rotacionada pelo ângulo α, com seta de força resultante (Fx, Fy) e axesHelper para referência.- Páginas integradas:
SignModule.tsx,BridgeModule.tsx,BarSelectorModule.tsx(substituídos os SVGs pelos novos 3D, mantendo o SVG oculto como fallback). - Suite de testes nova:
app/src/lib/__tests__/three-d-components.test.ts(8 testes validando exports e tipos). - Total: 182/182 testes passando (era 174/174).
Convenção visual (todos os 4 componentes):
- Placa/barra: cor base azul (#3b82f6), evolui para vermelho (#ef4444) conforme |Cx| ou |Cf| aumenta (intensity = min(1, |coeficiente|/max)).
- Vetor de força: cilindro (haste) + cone (ponta), comprimento proporcional a √(Fx² + Fy²) ou |F|.
- Marca amarela emissiva (#fbbf24) no ponto de aplicação.
gl={{ preserveDrawingBuffer: true, antialias: true }}para permitir captura de canvas (M9.3).onCreated={({ gl }) => registerCanvas(gl.domElement)}para registro automático nouseCaptureStore.OrbitControlscom limites para evitar câmera underground.
M9.7 — Sistema de import de projetos via JSON (~1 dia)
Status: ✅ Concluído (ver Marco 9.7 abaixo). Roundtrip completo testado. 29 testes novos (211/211 passando).
Marco 9.7 — Sistema de Import de Projetos via JSON
Status: ✅ Concluído (2026-07-07) Escopo: Permitir carregar projetos salvos em JSON de volta para a aplicação, completando o roundtrip com o export existente. Entregas:
app/src/lib/import-project.ts— 14 funções exportadas:parseProjectJson(text)— parsing seguro com mensagens clarasdetectFormat(parsed)— detectaSavedProjectvssnapshotvalidateSavedProject(raw)/validateSnapshot(raw)— validação separada de erros fatais e warnings não-fataisapplySavedProject(project)/applySnapshot(snapshot)— aplicação idempotente nos stores Zustand (windStore, galpaoStore)importProjectFromText(text)— orquestrador (parse + detect + validate + apply)readProjectFile(file)— wrapper FileReader → PromiseexportProjectToJson(project)/snapshotWindStoreToJson()— roundtrip- Tipo
ImportResultcomok,module,projectName,appliedFields,warnings,error
app/src/pages/SettingsModule.tsx— botão "Importar projeto" ao lado do "Exportar estado". Aceita.json. Mostra feedback inline com:- ✅ Sucesso: módulo aplicado, lista de campos
- ⚠️ Avisos: validações não-fatais
- ❌ Erro: mensagem formatada (JSON inválido, formato desconhecido, etc.)
app/src/lib/hooks/useProjects.ts— sem mudança (importação é via sistema de arquivos, não IndexedDB).- Suite de testes nova:
app/src/lib/__tests__/import-project.test.ts(29 testes cobrindo parsing, detecção, validação, aplicação e roundtrip). - Total: 211/211 testes passando (era 182/182).
Formatos suportados:
// Formato 1 — SavedProject (gerado pelo export IndexedDB)
{
"name": "Galpão Teste",
"module": "galpao",
"inputs": { "wind": {...}, "galpao": {...} },
"createdAt": 1234567890,
"updatedAt": 1234567899
}
// Formato 2 — Snapshot do windStore (gerado por "Exportar estado")
{
"v0": 40, "s1": 1, "s3": 1,
"terrainCategory": "II", "s3Group": 3,
"largestDimension": 30, "heightZ": 10,
"s2": 1.06, "vk": 42.4, "q": 1.1024,
"structureClass": "B"
}
Validação:
- Erros fatais: campos obrigatórios ausentes, tipos errados, valores inválidos (ex.: categoria fora de I–V)
- Warnings: campos opcionais ausentes (gerados automaticamente)
Aplicação idempotente:
- Cada campo só é aplicado se o tipo bater (number/string/boolean)
- Categoria validada contra enum antes de chamar setTerrainCategory
- Warnings não bloqueiam a aplicação dos demais campos
🟢 Baixa prioridade (features adicionais)
M9.8 — i18n completo (~2 dias)
Status: ✅ Concluído (ver Marco 9.8 abaixo). 130+ chaves no dicionário, LanguageSwitcher no sidebar, hook useI18n, persistência localStorage. 39 testes novos (250/250 passando).
Marco 9.8 — i18n completo (pt-BR + en-US)
Status: ✅ Concluído (2026-07-07) Escopo: Expandir o sistema de i18n mínimo (~15 strings) para cobrir toda a UI do VentoApp em pt-BR e en-US, com switcher de idioma e persistência local. Entregas:
app/src/lib/i18n.ts— Expandido para 130+ chaves organizadas por área (nav_, app_, common_, settings_, linear_loads_*, etc.). Mantém API públicat(key, locale, params?)com interpolação{placeholder}e fallback automático.app/src/lib/i18n.ts(novo): funções utilitáriasloadStoredLocale()/saveStoredLocale(locale)— persistênciadetectBrowserLocale()— fallback paranavigator.languagelistKeys()— debug/inspeção
app/src/store/i18nStore.ts— Zustand store com persistência. HookuseI18n()retorna{ t, locale, setLocale }. FunçãotNow(key)para tradução fora de componentes.app/src/components/LanguageSwitcher.tsx— Seletor compacto com ícone de globo (🇧🇷 pt-BR / 🇺🇸 en-US), integrado no rodapé do sidebar (desktop) e no header (mobile).- Páginas migradas:
App.tsx— sidebar, navegação (11 itens), HomeMock (header + cards)SettingsModule.tsx— Aparência, Projetos Salvos, Estado Atual, SobreLinearLoadsTable.tsx— 3 abas + 4 pilares + 6 terças + reaçõesExportMenu.tsx— tooltips dos botões
- Suite de testes nova:
app/src/lib/__tests__/i18n.test.ts(39 testes cobrindo dicionário, interpolação, persistência, detecção browser, componentes). - Total: 250/250 testes passando (era 211/211).
Convenção de chaves:
// snake_case agrupadas por área
nav_home, nav_warehouse, nav_cylinder, ...
settings_appearance, settings_projects, ...
linear_loads_title, linear_loads_pillar_windward, ...
scene_capture_format, ftool_title, ...
Interpolação:
t('settings_projects_count', 'pt-BR', { count: 5 })
// → "5 projeto(s) armazenado(s)."
Persistência:
- Chave localStorage:
ventoapp.locale - Valor:
'pt-BR' | 'en-US' - Fallback:
navigator.language→'pt-BR' - Falha silenciosa se localStorage indisponível (modo privado)
M9.9 — Validação contra exemplos do Blessmann (~2 dias)
Status: ✅ Concluído (ver Marco 9.9 abaixo). 10 casos documentados, 48 testes criados (298/298 passando).
Marco 9.9 — Validação cruzada contra Blessmann
Status: ✅ Concluído (2026-07-07) Escopo: Criar suite de validação que compara os cálculos do VentoApp com casos resolvidos do livro "O Vento na Engenharia Estrutural" (J. Blessmann, EDUFRGS, 2ª ed.) e com valores tabelados da norma. Entregas:
app/src/lib/blessmann-cases.ts— 10 casos clássicos documentados:# Caso Fonte 1 Galpão 30×15×6 m, telhado duas águas Blessmann Cap. 5 Ex. 5.1 2 Edifício alto 60×20×100 m, Cat. III Blessmann Cap. 9 3 Silo cilíndrico d=8, h=24, liso, topo aberto Tab. 13 4 S₂ em diferentes (h, categoria, classe) NBR 6123:2023 Tab. 3 5 S₃ analítico (Anexo B) NBR 6123:2023 Anexo B 6 Ponte 120 m, Pse NBR 6123:2023 sec. 11.2.2 7 Cobertura isolada (limites) NBR 6123:2023 sec. 7.2.1 8 Chaminé d=1,5, h=30, liso Tab. 13 9 Placa de publicidade 6×2 m Tab. 23 10 S₂ fórmula teórica vs Tab. 3 NBR 6123:2023 Tab. 1 + Tab. 3 - Cada caso exporta:
id,description,source,tolerance,notes? - Helper
isWithinTolerance(calculated, expected, tolerance)para comparação com tolerância percentual e absoluta (para expected=0). app/src/lib/__tests__/blessmann.test.ts— 48 testes cobrindo:- Casos quantitativos: S₂, S₃, Vₖ, q, Cpe, Pse
- Cross-checks: fórmula teórica vs tabela
- Propriedades: monotonicidade, consistência
- Helpers e metadados dos casos
Discrepâncias documentadas (pendências M9.1): Os testes para Tab. 6, Tab. 7, Tab. 13, Tab. 23 e Tab. 24-25 usam placeholders estruturais (apenas verifica que a função retorna valores finitos em faixas plausíveis). Quando M9.1 corrigir os valores oficiais, esses testes podem ser atualizados para validação ponto-a-ponto.
Total: 298/298 testes passando (era 250/250).
M9.10 — Tema dark mode para gráficos SVG (~0.5 dia)
Status: ✅ Concluído (ver Marco 9.10 abaixo). SVGs migrados para
var(--color-*), módulo svg-colors criado, 12 testes novos (310/310).
Marco 9.10 — Dark mode em gráficos SVG
Status: ✅ Concluído (2026-07-07) Escopo: Migrar cores hardcoded (#6366f1, #ef4444, etc.) nos gráficos SVG inline para variáveis CSS do tema, suportando dark mode. Entregas:
app/src/lib/svg-colors.ts— Módulo centralizado com 10 chaves semânticas:text=currentColor(herda de text-foreground)muted=var(--color-muted-foreground)primary/primaryFill(comcolor-mix(... transparent))destructive/destructiveFillinfo,grid,fgSolid,marker- Paleta
SVG_PALETTE(5 cores para multi-série, baseadas em--chart-1a--chart-5)
- SVGs migrados em 4 páginas:
DynamicsModule.tsx(2 gráficos: q(z) e ζ)IsolatedRoofModule.tsx(corte esquemático de cobertura)BarSelectorModule.tsx(barra + vetor de força, fallback)BridgeModule.tsx(ponte + pilares + vetores Cx/Cz, fallback)
- Substituições aplicadas:
#6366f1(roxo) →var(--color-primary)oucolor-mix(in oklch, var(--color-primary) 30%, transparent)#ef4444(vermelho) →var(--color-destructive)#94a3b8(cinza) →var(--color-border)#0f172a(preto) →var(--color-foreground)#1e293b(preto) →var(--color-foreground)#3b82f6(azul) →var(--color-primary)#cbd5e1(cinza claro) →var(--color-border)com opacity#fbbf24(amarelo) →var(--color-accent)(futuro)
app/src/lib/__tests__/svg-colors.test.ts— 12 testes:- Presença das chaves esperadas
- Validação de que cada cor referencia variável CSS
- Unicidade da paleta de multi-série
- Contraste semântico (primary ≠ destructive)
- Total: 310/310 testes passando (era 298/298).
Padrão de uso em componentes:
<svg viewBox="0 0 320 200">
<line stroke="var(--color-border)" strokeWidth="1" />
<path stroke="var(--color-primary)" fill="none" />
<text fill="currentColor">label</text>
</svg>
Vantagens:
- Cores se adaptam automaticamente a
.darkno html - Sem duplicação de lógica de tema
- Mantém fallback OKLCH via Tailwind v4
- Acessibilidade:
currentColorherda detext-foregroundda página
M9.13 — Exportação genérica de PDF para todos os módulos restantes
Status: ✅ Concluído (2026-07-08) Escopo: Expandir a capacidade de exportação de PDF (com captura 3D) que estava limitada ao Galpão para abranger os demais módulos (Cilindros, Abóbadas, Cúpulas, Muros, Coberturas Isoladas, Barras, Pontes, Dinâmica). Entregas:
- Criação de
app/src/lib/export-generic-pdf.tsxcontendo o componenteGenericReportDocumentcom template flexível capaz de receber seções dinâmicas (tabelas, grids de informações). - Injeção das funções
handleExportPDFem cada uma das páginas (CylinderModule.tsx,VaultModule.tsx,DomeModule.tsx,SignModule.tsx,IsolatedRoofModule.tsx,BarSelectorModule.tsx,BridgeModule.tsx,DynamicsModule.tsx). - Refatoração de
ExportMenu.tsxpara receber callbacks customizados, permitindo a exportação de PDF com suporte à visualização 3D para qualquer módulo de engenharia suportado pela NBR 6123. - Testes de build (
tsc -bevite build) passando com sucesso e mantendo a integridade (310/310 testes unitários sem regressões).
M9.11 — Persistência opcional em servidor (~especulativo)
Problema: Tudo é local (IndexedDB). Tarefa:
- Definir estratégia (Firebase? Supabase? REST própria?)
- Criar abstração
StorageAdapter(local ou remoto) - Adicionar autenticação básica
M9.12 — Testes E2E com Playwright (~2 dias)
Problema: Apenas testes unitários. Falta testar fluxos completos. Tarefa:
- Instalar
@playwright/test - Criar testes E2E para: criar projeto galpão, salvar, exportar PDF
- Integrar ao CI
📋 Convenções estabelecidas (manter)
- Tipagem forte: zero
as any, zero// @ts-ignore - Sem comentários exceto matemática complexa
- Imports absolutos:
@/lib/...,@/components/...,@/store/... - Componentes: PascalCase
.tsx, kebab-case utilitários.ts - Tabelas readonly:
Readonly<Record<...>>em todos osnbr-tables/ - Cpi sempre explícito:
p = q · (Cpe − Cpi)em todos os cálculos - Strategy pattern: cada tipo de estrutura tem um módulo em
lib/modules/ - Páginas: cada rota tem uma página em
pages/consumindo o módulo correspondente - Testes Vitest: cobrem motor matemático, interpolações, Cpi, vizinhança, Reynolds
- Validação antes de merge:
npm run build+npm testdevem passar
🔍 Onde encontrar coisas
Quero adicionar uma tabela NBR
→ app/src/lib/nbr-tables/ (criar table-N.ts), depois expor em coefficients.ts ou modules/
Quero adicionar uma nova estrutura (ex.: chaminé)
→ Criar app/src/lib/modules/<tipo>.ts com Strategy, depois app/src/pages/<Tipo>Module.tsx, registrar rota em App.tsx
Quero adicionar nova UI
→ Componentes em app/src/components/, com cn() para merge de classes, variantes shadcn quando existirem
Quero adicionar testes
→ app/src/lib/__tests__/ com vitest (sem jsdom necessário para cálculos puros)
Quero debugar o cálculo
→ app/src/lib/wind-kernel.ts é o ponto de entrada; cada função retorna valor com toFixed(...) para debug
🐛 Erros conhecidos (não críticos)
@rolldown/binding-linux-x64-gnuprecisa estar instalado (foi adicionado em Marco 1)- Binários em
node_modules/.bin/perdem o bit de execução — usarchmod +xantes de chamar - Vitest sem
vitest.config.tsseparado não funciona; foi criado em Marco 8 - TypeScript
noUnusedLocalsestá habilitado —void inputfoi adicionado para silenciar (M9.5 deve corrigir)
📚 Documentos relacionados
PLAN.md— Plano original dos 8 marcosapp/README.md— Documentação técnica do appAGENTS.md— Guia para IAsplano_tecnico_implantacao.md— Plano técnico original do projetoprojeto_vento_visao_geral.md— Visão geral do produto
🎯 Próximo passo sugerido
M9.7 já está completo. Para próximos passos, considerar:
M9.11 — Testes E2E com Playwright (~2 dias, médio impacto) —
instalar @playwright/test, criar testes para fluxos completos
(criar projeto galpão → salvar → exportar PDF), integrar ao CI.
Para retomar:
- Ler este documento
- Escolher item do roadmap restante
- Implementar e validar com testes
- Atualizar este documento marcando o item como concluído