# 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: > 1. Estado exato em que o projeto está HOJE > 2. Tudo o que foi entregue (com paths) > 3. Comandos para validar o estado > 4. Roadmap priorizado das próximas melhorias > 5. Convenções estabelecidas que devem ser mantidas --- ## 📊 Estado atual | Item | Valor | |------|-------| | Data da última atualização | 2026-07-10 | | 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 ✅ + M9.14 ✅ + M9.15 ✅ + M9.16 ✅ | | Cobertura NBR 6123:2023 | **100% das 11 seções + 3 anexos** | | Linhas de código TS/TSX | ~8.200 | | Arquivos `.ts`/`.tsx` no `src/` | **120** | | Páginas (rotas) | **10** | | Módulos Strategy | **7** | | Tabelas da norma implementadas | **36 / 36** + 3 anexos (auditadas M9.1) | | Testes Vitest | **316 passando / 316 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 rajada - `app/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 categoria - `app/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 + linear - `app/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 C - `app/src/lib/stations-lookup.ts` — Busca por nome/IBGE - `app/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 água - `app/src/lib/nbr-tables/table-9.ts` — Cpe telhados duas águas com calha - `app/src/lib/nbr-tables/table-10.ts` — Cpe telhados múltiplos simétricos - `app/src/lib/nbr-tables/table-11.ts` — Cpe telhados múltiplos assimétricos - `app/src/lib/nbr-tables/table-12.ts` — Cpe telhados com água vertical - `app/src/lib/coefficients.ts` — Interface unificada - `app/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) + requisitos - `app/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 terreno - `app/src/lib/nbr-tables/table-22.ts` — Cúpulas sobre parede cilíndrica - `app/src/lib/modules/cylinder.ts`, `vault.ts`, `dome.ts` — Strategy - `app/src/components/three/Cylinder3D.tsx`, `Vault3D.tsx`, `Dome3D.tsx` - `app/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/placas - `app/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 planas - `app/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 K - `app/src/lib/nbr-tables/table-29.ts` — Cf fios/cabos - `app/src/lib/nbr-tables/table-30.ts` — Componentes em faces de torre - `app/src/lib/modules/truss.ts` — Reticulados isolados/múltiplos - `app/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 triangulares - `app/src/lib/modules/bridge.ts` — Pse, Cx/Cz, flutter, galope - `app/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 + Vcr - `app/src/lib/comfort.ts` — a_lim ISO 10137 - `app/src/lib/modules/dynamics.ts` — Re-export consolidado - `app/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 projetos - `app/src/lib/theme.tsx` — ThemeProvider (light/dark/system) - `app/src/lib/i18n.ts` — Strings pt-BR/en-US - `app/src/pages/SettingsModule.tsx` — Tema + projetos + estado - `app/vitest.config.ts` — Configuração Vitest - `app/src/lib/__tests__/` — 5 suites de testes (38 testes) - `app/index.html` — Atualizado (lang, title, description) - `app/README.md` — Documentação completa - `AGENTS.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 pilar - `getPillarBaseReaction(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/J - `getAllPillarBaseReactions(...)` → reações nos 4 pilares - `getDragForce(...)` → 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 URL - `captureCanvasImage(canvas, options)` → captura + redimensionamento - `downloadImage(dataUrl, filename)` → download direto - `estimateDataUrlSizeKB(dataUrl)` → estimativa de tamanho - `dataURLtoBlob(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)}` - `app/src/lib/export-pdf.tsx` — Nova seção 5 (entre Coeficientes e Cargas Lineares) com `` 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: true` no contexto WebGL para permitir `toDataURL`. - `Image as PdfImage` do `@react-pdf/renderer` aceita 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 ASCII - `exportGalpaoToFtool()` → 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ões `void` em 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` por interfaces `VaultCpeWindPerpendicular` / `VaultCpeWindParallel` (expostos da tabela). - **Correção de bugs latentes em interpolação:** - `bilinear-interp.ts`: `findBracket` agora trata arrays de 1 elemento corretamente (evita `xs[-1]` quando length=1). - `log-interp.ts`: `findBracket` idem. - **Flags TypeScript adicionadas:** `noImplicitOverride` em `tsconfig.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:** ```ts // 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 de `T18` (0.25, 0.5, 1) não casam com `FL` (0.05, 0.1, 0.2, 0.3, 0.4). - `table-21.ts` e `table-22.ts`: usam `f.toString()` mas `T21`/`T22` têm chaves literais como `'1/15'` — `lookup` retorna `undefined`. - 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-*.ts` e `stations.ts` agora têm cabeçalho com `Fonte: NBR 6123:2023, p. XX` e `Ú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. - **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 ```bash cd /root/Apps/windapp/app # 1. Compilação TS (deve passar sem erros) ./node_modules/.bin/tsc -b # 2. Testes (deve mostrar 316/316 passing) ./node_modules/.bin/vitest run # 3. Lint (deve mostrar 0 errors, ~10 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 16 passed (16) | Tests 316 passed (316)` - ✅ oxlint: `Found 10 warnings and 0 errors` - ✅ vite: `✓ built in ~2.5s` com `dist/assets/index-*.js ~3.2 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/*.ts` com 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 no `useCaptureStore`. - `OrbitControls` com 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 claras - `detectFormat(parsed)` — detecta `SavedProject` vs `snapshot` - `validateSavedProject(raw)` / `validateSnapshot(raw)` — validação separada de erros fatais e warnings não-fatais - `applySavedProject(project)` / `applySnapshot(snapshot)` — aplicação idempotente nos stores Zustand (windStore, galpaoStore) - `importProjectFromText(text)` — orquestrador (parse + detect + validate + apply) - `readProjectFile(file)` — wrapper FileReader → Promise - `exportProjectToJson(project)` / `snapshotWindStoreToJson()` — roundtrip - Tipo `ImportResult` com `ok`, `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:** ```jsonc // 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ública `t(key, locale, params?)` com interpolação `{placeholder}` e fallback automático. - `app/src/lib/i18n.ts` (novo): funções utilitárias - `loadStoredLocale()` / `saveStoredLocale(locale)` — persistência - `detectBrowserLocale()` — fallback para `navigator.language` - `listKeys()` — debug/inspeção - `app/src/store/i18nStore.ts` — Zustand store com persistência. Hook `useI18n()` retorna `{ t, locale, setLocale }`. Função `tNow(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, Sobre - `LinearLoadsTable.tsx` — 3 abas + 4 pilares + 6 terças + reações - `ExportMenu.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:** ```ts // 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:** ```ts 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` (com `color-mix(... transparent)`) - `destructive` / `destructiveFill` - `info`, `grid`, `fgSolid`, `marker` - Paleta `SVG_PALETTE` (5 cores para multi-série, baseadas em `--chart-1` a `--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)` ou `color-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:** ```tsx label ``` **Vantagens:** - Cores se adaptam automaticamente a `.dark` no html - Sem duplicação de lógica de tema - Mantém fallback OKLCH via Tailwind v4 - Acessibilidade: `currentColor` herda de `text-foreground` da 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.tsx` contendo o componente `GenericReportDocument` com template flexível capaz de receber seções dinâmicas (tabelas, grids de informações). - Injeção das funções `handleExportPDF` em 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.tsx` para 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 -b` e `vite build`) passando com sucesso e mantendo a integridade (310/310 testes unitários sem regressões). ### M9.16 — Ferramenta de Auditoria LLM (Settings → Testes) **Status:** ✅ Concluído (2026-07-10) **Escopo:** Criar ferramenta temporária (dentro da página de Configurações, aba "Testes") que valida os cálculos do VentoApp contra a NBR 6123:2023 usando LLMs sequenciais. 110+ cenários de teste cobrindo todos os 10 módulos de estrutura + edge cases + variantes de Cpi. **Entregas:** - `app/src/lib/audit/types.ts` — Tipos centrais: `AuditScenario`, `AuditConfig`, `AuditReport`, `ScenarioResult`, `CheckStatus`, `LLMProvider`, `RouteModuleMap` - `app/src/lib/audit/norm-reference.ts` — Dados extraídos das tabelas existentes (S₂, Cpe paredes/telhados, cilindros, pontes, fórmulas dinâmicas) para servir como ground-truth ao LLM - `app/src/lib/audit/invariantes.ts` — 35+ regras da NBR 6123 (limites de Cpi, fórmula q, ranges de S₂, etc.) - `app/src/lib/audit/scenarios.ts` — Gerador de 110+ cenários: Blessmann (10), varredura de geometrias (galpão, cilindro, ponte, placa, torre), variantes de Cpi (6 casos), edge cases (z mínimo, saturação, V₀, classe), cross-module, dinâmica (conforto) - `app/src/lib/audit/serializer.ts` — Serialização de cenário para texto (formato legível por LLM) - `app/src/lib/audit/prompt-builder.ts` — Montagem do prompt: system (norma + invariantes) + user (cenários serializados) - `app/src/lib/audit/runner.ts` — Chamada a 4 provedores (OpenAI, Anthropic, MiniMax, OpenRouter) + Ollama local com retry, timeout 180s, `runAudit()` orquestrador - `app/src/lib/audit/parser.ts` — Parse da resposta JSON do LLM + `buildAuditReport()` que agrupa por módulo - `app/src/lib/audit/export-audit-pdf.tsx` — PDF do relatório via `@react-pdf/renderer` - `app/src/components/AuditPanel.tsx` — Painel principal: config (provider/model/key), executar, barra de progresso, tabela de resultados por módulo - `app/src/components/AuditDetailPopup.tsx` — Dialog com FallbackDiagram SVG + tabela de checks + inputs JSON + botões Exportar PDF / Copiar para módulo - `app/src/pages/SettingsModule.tsx` — Adicionada aba "Testes" via `Tabs` (Configurações + Testes) - `app/src/lib/i18n.ts` — 30 chaves de tradução para auditoria (pt-BR + en-US) - **Total:** 316/316 testes passando (era 310/310). **Provedores suportados:** | Provedor | Modelo padrão | API Base | |----------|---------------|----------| | OpenAI | `gpt-4o` | `api.openai.com/v1` | | Anthropic | `claude-3-5-sonnet-latest` | `api.anthropic.com/v1` | | MiniMax | `minimax-m3.0` (ou m2.7) | `api.minimax.chat/v1` | | OpenRouter | `openai/gpt-4o` (qualquer model) | `openrouter.ai/api/v1` | | Ollama | `deepseek-r1` (local) | `localhost:11434` | **Arquitetura:** - Cálculo puro offline: `scenarios.ts` gera 110+ cenários com inputs/referências/faixas esperadas - Prompt enviado ao LLM com a norma como contexto (invariantes + tabelas) - LLM retorna JSON por cenário: `{ scenarioId, verdict, checks[], summary }` - `buildAuditReport()` agrega por módulo (galpão, cilindro, etc.) - Interface em Settings → Testes: escolhe provedor, executa, vê resultado em tabela - Detalhes em popup com diagrama SVG 2D + checks individuais + inputs - PDF exportável com resumo + todos os checks por módulo - Botão "Copiar para o módulo" navega para rota correspondente **Inputs validados:** V₀, S₁, S₂, S₃, Cpi (6 casos), Cpe paredes (4 faces), Cpe telhados (6 zonas), drag, atrito, coeficientes de cilindros (Re, h/d, perfil), classificação de pontes (Pse, Vit), Cf de placas, conforto humano (ISO 10137), parâmetros de torres. #### M9.14 — Manual Didático Interativo com Animações SVG **Status:** ✅ Concluído (2026-07-10) **Escopo:** Criar um super manual colorido, ilustrativo e acessível com explicações interpretativas da norma NBR 6123, incluindo fluxos de vento animados em SVG para todos os módulos (Cilindros, Galpões, Cúpulas, Abóbadas, Muros, Pontes, Barras, Coberturas Isoladas). **Entregas:** - `app/src/components/WindFlowGrid2D.tsx` robusto e inteligente, renderizando variações didáticas automáticas para cada módulo (ex: vento a 0° vs 90° em galpões, e forças +Fz de arrancamento na borda de coberturas). - Animações fluídas em CSS: `wind-line-slow` (fluxo laminar) e `wind-line-fast` (fluxo acelerado/sucção, em roxo para fácil distinção). - Zonas de esteira turbulenta e setas vetoriais (Cpi, Sustentação/Downforce) acopladas ao SVG com legendas dinâmicas perfeitamente combinadas à exibição. - Suporte estrito e bonito ao modo Dark / Light, fugindo de cores agressivas (usando tailwind `dark:bg-*`). - Componente em barra lateral `EducationalManual.tsx` disponível universalmente em todas as views. #### M9.15 — Rebranding e Oficialização: BrainWind v1.0 **Status:** ✅ Concluído (2026-07-10) **Escopo:** Oficializar o nome e versão do produto alterando referências legadas ("VentoApp", "appvento") para **BrainWind v1.0**. **Entregas:** - Modificação no `index.html` (SEO, `` e meta description). - Atualização em massa dos dicionários globais (`i18n.ts`) refletindo nos headers da UI principal. - Adequação do rodapé dos manuais didáticos, bem como de todos os geradores de memórias de cálculo em PDF (`export-pdf.tsx`, `export-generic-pdf.tsx`). - Correção nos scripts geradores de inputs para o software estrutural Ftool (`export-ftool.ts`). - Atualização e refatoração nas asserções das suítes de testes (`i18n.test.ts`, `export-ftool.test.ts`) para suportar a validação do novo nome. #### 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) 1. **Tipagem forte**: zero `as any`, zero `// @ts-ignore` 2. **Sem comentários** exceto matemática complexa 3. **Imports absolutos**: `@/lib/...`, `@/components/...`, `@/store/...` 4. **Componentes**: PascalCase `.tsx`, kebab-case utilitários `.ts` 5. **Tabelas readonly**: `Readonly<Record<...>>` em todos os `nbr-tables/` 6. **Cpi sempre explícito**: `p = q · (Cpe − Cpi)` em todos os cálculos 7. **Strategy pattern**: cada tipo de estrutura tem um módulo em `lib/modules/` 8. **Páginas**: cada rota tem uma página em `pages/` consumindo o módulo correspondente 9. **Testes Vitest**: cobrem motor matemático, interpolações, Cpi, vizinhança, Reynolds 10. **Validação antes de merge**: `npm run build` + `npm test` devem 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) 1. **`@rolldown/binding-linux-x64-gnu`** precisa estar instalado (foi adicionado em Marco 1) 2. **Binários em `node_modules/.bin/`** perdem o bit de execução — usar `chmod +x` antes de chamar 3. **Vitest** sem `vitest.config.ts` separado não funciona; foi criado em Marco 8 4. **TypeScript `noUnusedLocals`** está habilitado — `void input` foi adicionado para silenciar (M9.5 deve corrigir) --- ## 📚 Documentos relacionados - `PLAN.md` — Plano original dos 8 marcos - `app/README.md` — Documentação técnica do app - `AGENTS.md` — Guia para IAs - `plano_tecnico_implantacao.md` — Plano técnico original do projeto - `projeto_vento_visao_geral.md` — Visão geral do produto --- ## 🎯 Próximo passo sugerido **M9.16 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: 1. Ler este documento 2. Escolher item do roadmap restante 3. Implementar e validar com testes 4. Atualizar este documento marcando o item como concluído