📁 Documentação Técnica Oficial

WPM Gestão Interna
Fase Browser-Only

34 versões. Centenas de horas. Zero budget. Um recepcionista que transformou frustração operacional em sistema — e documentou cada decisão, cada regressão, cada aprendizado. Avaliado com 9,5/10 por QA sênior. Este documento é o registro completo dessa jornada.

Autor Wallace Phillip Maclayne
Versão Final v34 — WPM Gestão Interna
Arquitetura SPA Single-File Client-Side
Status ✓ Fase Concluída
Avaliação QA 9,5 / 10
01 — Origem
De onde veio o projeto

Como uma planilha de controle manual se tornou um sistema web completo rodando inteiramente no browser.

O Problema Original

O controle operacional da recepção da unidade WPM era feito de forma manual: planilhas, anotações em papel, WhatsApp para pendências. Dados de alunos novos, vendas de addons, NPS e escala de trabalho não tinham uma fonte única da verdade.

Cada recepcionista registrava informações de forma diferente. Relatórios mensais levavam horas para compilar. Pendências se perdiam entre conversas.

A Decisão

A solução foi criar um sistema digital próprio. A escolha de começar como um único arquivo HTML foi deliberada: sem servidor, sem deploy, sem dependências externas. Qualquer computador com um browser poderia abrir e usar imediatamente.

Isso eliminou a barreira de entrada e permitiu iterações rápidas. O arquivo poderia ser passado por pen-drive, WhatsApp ou e-mail.

Escopo Inicial — O que precisava existir

Operacional

Registro de alunos novos com atendente responsável, vendas de addons vinculadas aos atendimentos, controle de pendências com status e responsáveis.

Gestão

Dashboard executivo com métricas do mês, NPS com ranking de recepcionistas, escala de trabalho mensal com regras trabalhistas.

Infraestrutura

Segregação por período mensal, exportação e importação de backups JSON, sistema de fechamento mensal que avança o período automaticamente.

02 — Conceito
O que é o sistema

WPM Gestão Interna — um sistema operacional completo de gestão de recepção rodando 100% no browser, sem backend.

Definição Técnica

O sistema é uma Single Page Application (SPA) single-file — um único arquivo .html com todo o HTML, CSS e JavaScript embutidos (~11.500 linhas na v34). O estado é armazenado em IndexedDB como backend primário e localStorage como espelho de fallback, segregado por período no formato YYYY-MM. Não há servidor, não há banco externo, não há login.

A arquitetura é dividida em camadas explícitas: config → persistência → schema → domínio/seletores → renderização → UI/eventos → diagnósticos. Todo o contrato de atualização de estado é explícito: Ação → Mutação → saveData() → requestRender().

Equipe Gerenciada

Recepcionistas

Wallace, PESSOA 2, PESSOA 3, PESSOA 4 — atendentes de alunos novos e hostess de pendências.

Professores

PESSOA A, PESSOA B, PESSOA C, PESSOA D, PESSOA E, PESSOA F, PESSOA G — aparecem na escala. PESSOA G não pode fazer abertura aos sábados e feriados (restrição interjornada).

Períodos Mensais

O sistema trata cada mês como uma unidade isolada. Dados de 2026-01 nunca vazam para 2026-02. O sistema suporta navegação completa entre períodos históricos com dados preservados.

Campos deriváveis — como dia da semana a partir de uma data — nunca são salvos no storage. São calculados em tempo de execução para economizar quota de armazenamento.

03 — Números
A escala da fase
34
Versões Produzidas
11.5k
Linhas na Versão Final
8
Módulos Completos
9.5
Nota QA Sênior (Gemini Pro)
7
Camadas de Arquitetura
2
Backends de Storage (IDB + LS)
120
Limite Cache Seletores (Map)
30
Alunos/mês Gerados (RNG seed)
04 — Arquitetura
Sistema de camadas

A separação de responsabilidades não é apenas conceitual — está formalizada no objeto APP_INTERNALS, que mapeia e expõe todas as funções públicas de cada camada para diagnóstico e inspeção em console.

Fluxo de Dados

O estado da aplicação é centralizado em duas variáveis: storage (store global com todos os períodos) e state (referência direta ao período ativo). Toda mutação passa por funções de ação que atualizam state, chamam saveData() e disparam requestRender() para as áreas afetadas.

Não há setState reativo ou framework. O contrato de atualização é explícito, auditável e determinístico.

Inicialização em Etapas

A inicialização é assíncrona e segue sequência rígida: (1) hydrateStorageCache — lê IDB + localStorage em paralelo; (2) syncAppState — normaliza o store; (3) bindings de UI; (4) initializeForms; (5) renderInitialViews + diagnósticos. Falhas mostram toast de erro sem travar a interface.

⚙️
Config
Constantes globais, versões, defaults de negócio (APP_DEFAULTS, STORAGE_KEY, STORE_VERSION, APP_VERSION).
Camada 1
💾
Persistência
CRUD sobre IDB/localStorage, cache Map, fila serializada de operações, broadcast cross-tab.
Camada 2
🔧
Schema
Normalização, migração, sanitização, versionamento de store, construção de períodos.
Camada 3
📊
Domínio / Seletores
Derivação de dados, cálculos, ranking, filtragem, memoização por assinatura de dados.
Camada 4
🖥️
Renderização
Geração de HTML, diff de strings, patch seletivo do DOM por ID, fila com coalescing.
Camada 5
🎮
UI / Eventos + Diagnósticos
Event delegation, modais, tabs, atalhos de teclado, smoke tests, auditoria de períodos.
Camadas 6–7

APP_INTERNALS — Mapa Formal dos Módulos

O objeto Object.freeze(APP_INTERNALS) expõe explicitamente, por categoria, todas as funções internas do sistema: config, persistence, schema, domain, actions, rendering, ui e diagnostics. Disponível em window.__APP_INTERNALS__ para inspeção em DevTools sem necessidade de quebrar o arquivo.

05 — Stack
Tecnologias utilizadas

Zero build tools. Zero Node.js. Zero backend. Tudo nativo no browser — sem CDNs externas na v34, sem dependências de rede em runtime.

Core — 100% Nativo

Vanilla JavaScript HTML5 CSS3 IndexedDB API localStorage API Blob API FileReader API crypto.randomUUID() IntersectionObserver HTML5 Drag & Drop API

Padrões de Engenharia

Dual-Storage (IDB + LS) In-Memory Cache (Map) Serialized Write Queue Cross-Tab Broadcast HTML Diff Patch Memoized Selectors Seeded RNG Schema Migration Smoke Test Suite

Persistência Dual

IndexedDB como backend primário (assíncrono, sem limite restritivo). localStorage como espelho síncrono e fallback. Cache Map em memória elimina leituras desnecessárias. Fila serializada via queueStorageOperation previne race conditions.

Renderização Eficiente

aplicarHtmlSeMudou() compara string HTML nova com innerHTML atual antes de tocar o DOM. aplicarPatchCards() faz diff por ID em listas. requestRender() com fila de coalescing evita renders redundantes em cascata.

Seletores Memoizados

lerSelectorMemorizado() armazena resultados indexados por período + nome + assinatura JSON. Cache com limite de 120 entradas antes de limpeza automática — evita memory leak em sessões longas.

06 — Módulos
Os 8 módulos do sistema

Cada módulo tem lógica de domínio, seletor memoizado, formulário modal, render independente e re-render seletivo.

🎓
Alunos (Students)
Tabela com 11 colunas. Busca accent-insensitive em tempo real. Filtros por atendente e feedback. Barra de resumo com 12 células agrupadas. Modal de cadastro/edição com validação.
Completo
💊
Addons
Grid diário por recepcionista × tipo de addon. Estrutura addons[pessoa][tipo][dia]. resizeMonth() ajusta arrays preservando dados existentes. Totais memoizados por assinatura.
Completo
📋
Pendências (Kanban)
Kanban com 3 colunas e drag-and-drop nativo. Busca accent-insensitive por nome, matrícula, pendência e hostess. Status persistido. Dashboard mostra top 4 prioritários.
Completo
NPS
Score 0–100, metas mensal e semestral, observações com debounce de 800ms. Ranking com setas de tendência (↑↓) comparando com rankSnapshot anterior.
Completo
📅
Escala
Controle por dia com recepcionista, swap de recepção e turnos de professores com flag de troca. Seletor memoizado computa dias cobertos, trocas e fins de semana.
Completo
🗓️
Eventos
Lista (cards + tabela) + calendário mensal com pills de eventos por dia (máx 3 visíveis). Tipos: Ação, Campanha, Treinamento, Feriado, Evento. Filtros por tipo e status.
Completo
📊
Dashboard
Indicadores derivados de todos os módulos via selecionarIndicadoresDashboard memoizado. KPIs de NPS, feedback, addons, próxima escala, próximo evento e pendências críticas.
Completo
🔧
Configurações + Diagnósticos
Gestão de equipe, tipos de addon, auditoria de períodos, painel técnico de persistência, smoke tests, health bar e controles de export/import/reset.
Completo
07 — Persistência
Sistema de armazenamento dual

A camada de maior maturidade técnica do projeto. IndexedDB primário + localStorage espelho, mediados por cache em memória e fila serializada de escritas.

IndexedDB — Backend Primário

Preferido por suportar valores maiores, não bloquear a thread principal e ser mais adequado para dados estruturados. A função withIndexedDbStore() abstrai transações com promise wrapper. Singleton de conexão com idbOpenPromise evita aberturas paralelas.

localStorage — Espelho e Fallback

Mantido em sincronia após cada escrita no IDB. Garante compatibilidade com ambientes que bloqueiam IndexedDB, alimenta o storage event para broadcast cross-tab e serve como fallback imediato em leituras síncronas via readStoredValue().

Fila Serializada — Race Conditions Eliminadas

Toda escrita no backend passa por queueStorageOperation(), que enfileira operações assíncronas e as executa em sequência (nunca em paralelo). Previne corrupção silenciosa de dados em cenários de múltiplas escritas simultâneas — fonte recorrente de bugs em versões anteriores.

Broadcast Cross-Tab

Escritas emitem payload JSON em STORAGE_BROADCAST_KEY via storage event. Outras abas consomem via consumeStorageBroadcast(), resincronizam com syncAppState() e re-renderizam — estado consistente entre múltiplas instâncias abertas do sistema.

Gerenciamento de Quota + Snapshot Local

Toda operação de escrita trata QuotaExceededError explicitamente com toast orientativo. A interface de Configurações exibe uso estimado via Blob.size com barra de progresso e alerta acima de 80% dos 5MB estimados. Snapshot local salvo automaticamente a cada exportação, com timestamp exibido na health bar.

08 — Renderização
Pipeline de render sem framework

Diff de strings HTML, patch por ID, memoização por assinatura e fila com coalescing — sem React, sem Virtual DOM, sem build tool.

aplicarHtmlSeMudou — Diff de Strings

Antes de tocar o DOM, a função compara a string HTML nova com o innerHTML atual do elemento. Se forem idênticos, o DOM não é modificado — zero reflow, zero repaint. Especialmente eficaz em views ativas sem dados novos desde o último render.

aplicarPatchCards / Linhas — Diff por ID

Para listas de elementos (cards Kanban, linhas de tabela, cards de eventos), diff por ID: elementos existentes são atualizados só se o HTML mudou; novos são inseridos; removidos são eliminados. Preserva estado de foco e scroll sem recriar o DOM inteiro.

requestRender — Fila com Coalescing

A função requestRender(areas) enfileira áreas específicas (dashboard, students, addons, pending, nps, scale, events, settings, hero) sem renderizar imediatamente. O processo real acontece em microtask via Promise.resolve(), coalescendo múltiplas chamadas em um único ciclo — evita renders redundantes em cascata quando múltiplas ações ocorrem em sequência.

09 — Design System
Identidade visual e UX

Sistema de design CSS completo baseado em custom properties, com acessibilidade de teclado, ARIA completo e drag-and-drop nativo.

Design System CSS

Custom Properties

--bg, --primary (#FFC20F), --danger, --ok, --warning com variantes soft/strong. Aplicadas consistentemente em botões, pills, cards e gradientes.

Topbar Sticky com glassmorphism

backdrop-filter: blur(12px), z-index elevado, controles de período sempre visíveis durante scroll.

Tipografia Montserrat/Inter

Fonte principal com fallback para system-ui. JetBrains Mono para valores numéricos e código.

Acessibilidade e Teclado

ARIA Completo

Tabs com role=tablist/tab, aria-selected, tabindex dinâmico. Modais com role=dialog, aria-modal, foco retornado ao elemento de origem ao fechar.

Atalhos de Teclado

Setas ArrowLeft/Right + Home/End navegam entre abas. / foca busca da aba ativa. Esc fecha modal. Todos os botões com type="button" explícito.

Drag and Drop Nativo

HTML5 D&D API no Kanban. Highlight visual da coluna de destino. Classe dragging com transform e opacity durante o arraste.

Sidebar vs. Layout Convencional

Uma falha de layout crítica foi descoberta ao usar height:100vh; overflow:hidden em contêineres. Isso criava scroll traps e gaps de conteúdo. O padrão correto adotado: min-height:100vh no contêiner da app, scroll natural do body e position:sticky para elementos fixos.

10 — Evolução
Linha do tempo completa

34 versões produzidas ao longo da fase browser-only, agrupadas em 4 fases técnicas distintas.

v1 Base inicial
Conversão da planilha de controle para HTML. Dashboard, Alunos Novos, Addons, Pendências, localStorage e backup JSON. Primeira versão funcional.
v2–v3 Refinamentos iniciais
Estabilização da base. Correções de layout e comportamento do localStorage. Sem artefatos preservados — reconstruídos nas versões seguintes.
v4 Kanban robusto
Kanban de pendências com drag-and-drop, truncamento de textos longos, tooltip, rolagem suave, ESC para fechar modal e sincronização entre abas.
v5 Lógica operacional
Metas de NPS, conexão automática addon-aluno, refinamento do dashboard com insights executivos.
v6 ★ Base de referência sólida
Dashboard executivo completo, persistência de aba/filtros e atalho "/". Tornou-se a base de rollback para quando v7 regrediu. Lição: versões estáveis devem ser marcadas antes de evoluções arriscadas.
v7–v8 REGRESSÃO — Camada fora do layout
Adição de faixa extra abaixo das abas gerou interface disfuncional. Primeira grande crise do projeto.
v9 Rollback consciente para v6
Decisão de retornar à v6 como base segura. Lição: rollback não é fracasso, é engenharia responsável.
v10–v11 Gestão mensal + Escala e Eventos
Seletor de mês/ano, fechamento de período com backup JSON, aba de Escala visual e aba de Eventos/Ações. Cards executivos no dashboard.
v12–v17 Escala visual, calendário, filtros avançados
Grade visual de escala com legendas coloridas. Calendário de eventos. Filtros avançados, busca, exportações CSV. Maturidade operacional crescente.
v18–v20 Robustez incremental
Evoluções de funcionalidades e estabilidade. Fase de consolidação antes de mudanças de storage.
v21 REGRESSÃO SEVERA — Tela vazia
Migração de namespace de storage quebrou o estado. Sistema abria com tela completamente vazia sem mês ativo. Crise severa — usuário sem acesso a dados.
v22 Recuperação com namespace novo
Recuperação com namespace isolado de storage. Lição: migrations devem ter fallback automático e isolamento por versão.
v23–v26 Seed determinístico + Hotfixes
Seed determinístico de 30 alunos, 20 pendências, 10 eventos por mês via RNG com seed. Hotfixes para storage isolado, sanitização de filtros e ajustes Kanban.
v27–v28 ★ Snapshot + Autotestes — Baseline
Snapshot local, backup com metadados, diagnóstico do sistema, autotestes na aba Configurações cobrindo fluxos críticos. Esta se torna a baseline funcional oficial.
v29–v32 Desenvolvimento paralelo Claude + GPT
Metodologia dual. Claude produz versões com foco em segurança (esc(), sanitizeDeep, safeLocalSet). GPT produz versões com foco em UX e lógica unificada de reset de período.
v33 ★★ Merge deliberado — Versão consolidada
Base v31 (Claude — arquitetura de segurança) + patches cirúrgicos v32 (GPT — reset de período unificado). Passou todos os critérios de validação. Aprovada para testes operacionais reais.
v34 ★★★ FINAL Maturidade máxima da fase — IndexedDB + Diagnósticos
IndexedDB como backend primário, fila serializada de escritas (queueStorageOperation), broadcast cross-tab, APP_INTERNALS como mapa formal dos módulos, pipeline de render com diff + memoização completa. Avaliação externa Gemini Pro QA sênior: 9,5/10. Fase browser-only concluída.
11 — Crises
Regressões e o que causou cada uma

Cada crise foi documentada e gerou uma regra de arquitetura permanente.

v7–v8 — Camada fora do layout

O que aconteceu

Adição de uma faixa extra de botões abaixo das abas foi implementada fora da malha principal de layout. Interface quebrada, sobreposição de elementos e scroll incorreto.

Regra gerada

Expansões de layout devem ser testadas em todas as viewports. Componentes novos fora da malha têm custo alto de estabilidade.

v21 — Tela vazia ao abrir

O que aconteceu

Mudança no namespace de storage quebrou silenciosamente o carregamento do estado. Aplicação abria sem mês ativo e sem dados — completamente inutilizável. Usuário em produção afetado.

Regra gerada

Mudanças de storage precisam de fallback automático e migração com chaves legadas. readStoredJsonWithFallback() implementado como solução permanente.

v23–v24 — Dados de teste invisíveis

O que aconteceu

O localStorage reutilizava dados de versões anteriores. O seed determinístico gerava dados, mas com namespace da versão antiga — invisíveis na nova.

Regra gerada

Namespace isolado por versão. RNG baseado na chave do período (makeRng('wpm-YYYY-MM')) garante reprodutibilidade e isolamento total.

v13–v17 — Degradação por patches iterativos

O que aconteceu

Aplicação sequencial de str_replace em arquivo de 5000+ linhas gerou funções duplicadas, CSS desconectado e bugs acumulados. Qualidade degradou progressivamente.

Regra gerada

Patches iterativos em arquivos massivos são anti-padrão. Prefira reescrita atômica para mudanças estruturais.

12 — Lições
O que o projeto ensinou

Aprendizados técnicos e de processo que guiarão a próxima fase do sistema.

Patches iterativos acumulam erros em arquivos grandes

A degradação de v13 a v17 foi causada por múltiplos str_replace em um arquivo de 5000+ linhas. Cada patch introduzia pequenas inconsistências que se acumulavam. A solução é a reescrita atômica completa do arquivo quando há mudanças estruturais.

CSS não tipado é fonte constante de falhas de layout

A tabela de alunos usava a classe .pending-table (projetada para 8 colunas) numa tabela de 11 colunas. O calendário tinha classes definidas em JS mas ausentes no stylesheet. Regra: cada componente precisa de CSS dedicado com definição explícita de colunas.

Nenhuma IA é incondicionalmente superior — metodologia dual é o padrão

Claude tendeu a arquiteturas de segurança mais robustas (esc(), sanitizeDeep, safeLocalSet). GPT tendeu a fluxos UX mais coesos e lógica de reset unificada. Os melhores resultados vieram de merges deliberados com trilha de auditoria explícita.

Rollback consciente é engenharia responsável

A decisão de retornar à v6 quando v7–v8 falharam foi a decisão certa. Versões estáveis devem ser marcadas explicitamente antes de evoluções arriscadas. Rollback não é fracasso — é parte do processo de engenharia.

Validação antes de entregar é inegociável

O protocolo de validação da v34 — verificação de sintaxe JS, estrutura HTML, IDs/funções duplicadas, cobertura de esc(), autotestes de fluxo integrados — deve ser padrão em todas as entregas. Não existe "entrega rápida" sem validação.

Race conditions em storage exigem fila serializada

Múltiplas escritas assíncronas paralelas eram fonte de corrupção silenciosa de dados. A introdução de queueStorageOperation() na v34 eliminou definitivamente esse vetor de erro sem impacto visível de performance para o usuário.

13 — Segurança
Hardening do sistema

Sanitização em dois níveis independentes e complementares — na importação e na renderização.

Proteção XSS — Dois Níveis

Nível 1 — Importação: sanitizeDeep() remove < e > recursivamente de todo o JSON importado antes de qualquer processamento. Dados maliciosos não entram no store mesmo que escapem da validação de schema.

Nível 2 — Renderização: toda string de dados exibida no DOM passa pela função esc(), que escapa entidades HTML críticas. Proteção independente do caminho de entrada dos dados.

Normalização Defensiva

normalizeData() é chamada em todo ponto de entrada de dados: inicialização, importação, troca de período e salvamento de configurações. Garante que arrays existam, propriedades obrigatórias tenham valores válidos e referências inconsistentes sejam corrigidas automaticamente.

Nenhum dado bruto de usuário ou de import chega ao estado sem passar por normalização.

Sanitização de UIState

sanitizeUIState() valida o estado de UI persistido contra conjuntos de valores permitidos (validEventTypes, validEventStatuses, validTabs). Tabs inválidas são resetadas para dashboard. Migração automática de nomes legados de tabs.

Proteção do Storage

Todos os setItem() estão envolvidos em tratamento de QuotaExceededError via persistStoredValue(). Falhas de storage nunca ocorrem silenciosamente — o usuário recebe feedback claro com orientação de ação (exportar backup, limpar meses vazios).

14 — Diagnósticos
Sistema de autotestes integrado

Uma suíte de diagnósticos embutida que seria incomum mesmo em aplicações com stack completa de produção.

runSystemDiagnostics

Verifica integridade do store: existência e validade de todos os campos obrigatórios, coerência entre período ativo e store, ausência de referências quebradas (alunos com atendentes não cadastrados, pendências sem status válido). Resultados exibidos com pill de status (ok/warn/danger) e salvos em SYSTEM_REPORT_KEY.

runFlowSmokeTests

Suíte de smoke tests que simula fluxos completos — criação/edição/exclusão de alunos, troca de status de pendência, adição de eventos, troca de período e verificação de isolamento de dados. Opera sobre cópia do store para não contaminar dados reais. Resultados salvos em FLOW_TEST_REPORT_KEY.

renderPeriodAudit

Lista todos os períodos armazenados com métricas (alunos, pendências, eventos, escala, NPS, volume de addons) e status: Vazio / Completo / Revisar. Critério de "Completo": ≥30 alunos, ≥20 pendências, ≥10 eventos e escala > 0.

renderPersistenceTechPanel

Painel técnico em tempo real: modo de persistência ativo (IndexedDB ou localStorage), status da última operação, timestamp da última gravação, resultado do self-test de escrita/leitura, disponibilidade de broadcast cross-tab e versão do payload. Diagnóstico imediato sem abrir DevTools.

15 — Regras de Negócio
Regras invioláveis do sistema

Regras que não podem ser quebradas em nenhuma versão, presente ou futura do sistema.

1
Separação de roles — Recepcionistas vs. Professores

Alunos novos só podem ter um recepcionista como atendente. Pendências só aceitam recepcionistas como hostess. Professores só aparecem na escala. Esta regra reflete a hierarquia operacional real da unidade.

2
Sincronização addon-aluno bidirecional

Ao cadastrar aluno com addon, a venda é criada no módulo de Addons. Ao editar, o addon é atualizado. Ao excluir, o addon é removido. Não pode existir addon órfão.

3
Regra dos 7 Dias na Escala

Um funcionário não pode ser escalado no sábado E no domingo da mesma semana. Como trabalham de segunda a sexta (5 dias), trabalhar nos dois dias do fim de semana resultaria em 7 dias consecutivos — acima do limite legal de 6 dias.

4
Restrição de Abertura — PESSOA G

PESSOA G não pode pegar turnos de abertura (prof1) aos sábados ou feriados por conta do descanso interjornada. A lógica retorna false para PESSOA G nestas situações. Esta restrição deve ser preservada em todas as versões futuras.

5
Datas em formato ISO — Sem bugs de fuso horário

Todos os campos de data no storage usam YYYY-MM-DD. Nunca armazenar strings localizadas ou timestamps com timezone. Previne bugs de fuso horário onde uma data se torna o dia anterior ou posterior dependendo do browser.

6
Segregação total por período

Dados do período 2026-03 nunca devem vazar para 2026-02 ou 2026-04. Toda operação que lê ou escreve dados verifica o período ativo correto. Reset de mês limpa apenas o período selecionado, preservando apenas a configuração da equipe.

7
Nenhuma escrita de storage sem tratamento de quota

Toda operação de persistência passa por persistStoredValue() que trata QuotaExceededError explicitamente. Escrita direta via localStorage.setItem() sem tratamento é proibida arquiteturalmente na v34.

16 — Validação
Auditoria da versão final v34

Critérios de validação obrigatórios, todos verificados antes da aprovação da versão final.

Critério Ferramenta / Método Resultado Status
Sintaxe JavaScript node --check + inspeção manual Zero erros ✓ PASS
Estrutura HTML Parser HTML — tags abertas/fechadas Zero tags não fechadas ✓ PASS
Funções duplicadas grep + análise manual Zero duplicatas ✓ PASS
IDs duplicados grep + detecção automatizada Zero IDs duplicados ✓ PASS
Cobertura esc() Auditoria de todos os innerHTML dinâmicos Todos os pontos cobertos ✓ PASS
sanitizeDeep() na importação Trace de fluxo de importData() Aplicado antes de qualquer merge ✓ PASS
Fila de storage (queueStorageOperation) Code review + smoke test de escritas paralelas Toda escrita serializada ✓ PASS
IndexedDB como primário Trace de persistStoredValue() IDB precede localStorage em todas as escritas ✓ PASS
Broadcast cross-tab Teste com 2 abas simultâneas Estado sincronizado entre abas ✓ PASS
Seletores memoizados Inspeção de cacheSelectores Map Todos os seletores derivados memoizados ✓ PASS
runFlowSmokeTests Painel de Configurações → Autotestes Todos os fluxos CRUD aprovados ✓ PASS
runSystemDiagnostics Painel de Configurações → Diagnósticos Zero erros de integridade ✓ PASS
APP_INTERNALS completo window.__APP_INTERNALS__ em DevTools Todas as 8 camadas mapeadas ✓ PASS
RNG seed determinístico Geração de dados em 3 sessões independentes Dados idênticos por período em todas as sessões ✓ PASS
Reset de período Teste funcional — reset + validação Preserva só equipe, zero dados residuais ✓ PASS
15/15
Critérios de Validação Aprovados
v34 — WPM Gestão Interna aprovada como versão final da fase browser-only
9,5 / 10 Avaliação Gemini Pro QA Sênior
17 — Metodologia
Desenvolvimento com IA dual

Uma abordagem diferenciada: desenvolvimento paralelo com Claude (Anthropic) e GPT (OpenAI), com merges deliberados e avaliação crítica bilateral.

Claude (Anthropic)

Pontos fortes identificados

Arquitetura de segurança consistentemente mais robusta. Cobertura sistemática de esc() em todos os pontos de injeção. Implementação padronizada de sanitizeDeep(), camadas de persistência e diagnósticos integrados.

Área de melhoria

Algumas escolhas de UX menos intuitivas. Padrão de reset de período com lógica mais fragmentada em versões anteriores.

GPT (OpenAI)

Pontos fortes identificados

Fluxos UX mais coesos e intuitivos. Lógica unificada de reset de período com buildCleanPeriod() mais elegante. Menor fragmentação do estado de UI.

Área de melhoria

Cobertura de segurança menos sistemática. Tendência a simplificar sanitização em favor de brevidade de código.

Como o merge foi feito na V33 → base para v34

Base: V31 (Claude)

Toda a arquitetura de segurança — esc(), sanitizeDeep(), confirmações destrutivas, camadas de persistência. O esqueleto do sistema.

Patches: V32 (GPT)

Lógica unificada de resetSelectedMonth() e closeCurrentMonth() usando buildCleanPeriod(). Melhorias no fluxo de navegação entre períodos.

V34 (Refinamento final)

Evolução sobre o merge: IndexedDB dual, fila serializada, broadcast cross-tab, APP_INTERNALS, pipeline de render otimizado. Fase browser-only concluída.

Princípio da Avaliação Crítica Bilateral

Maclayne avalia ambas as IAs criticamente e espera que cada IA faça o mesmo com a outra. Não existe "a IA certa". Existe a análise técnica do output de cada uma, identificação dos pontos fortes de cada versão, e a síntese deliberada na versão final. Esta metodologia produziu resultados consistentemente superiores às versões produzidas por uma única IA em isolamento.

18 — Próxima Fase
A evolução para full-stack

A fase browser-only foi o laboratório de regras de negócio. A próxima fase é a migração para arquitetura profissional com banco de dados, API e frontend componentizado.

Visão da Nova Arquitetura

O sistema browser-only provou as regras de negócio em condições reais. Agora o objetivo é evoluir para uma arquitetura que suporte múltiplos usuários simultâneos, banco de dados relacional, autenticação, CI/CD e testes automatizados E2E.

O v34.html passa a ser a referência funcional oficial — jamais reescrito, mas lido como fonte da verdade de comportamento e regras de negócio.

Frontend

React + TypeScript + Vite
SPA componentizada, type-safe, hot reload
🎨
Tailwind CSS
Design system atomic, mesma paleta WPM
🔗
React Query / TanStack
Cache, sincronização e estado do servidor

Backend

Node.js + Fastify + TypeScript
API REST de alta performance, validação Zod
🐘
PostgreSQL + Prisma
Banco relacional, migrations, type-safe ORM
🧪
Vitest + Playwright
Unit tests API + E2E dos fluxos críticos

Roadmap por Sprints

Sprint 0 — Fundação

Monorepo, Docker PostgreSQL, TypeScript configurado, ESLint/Prettier, README de setup local.

Sprint 1 — Modelagem

Schema Prisma com todas as entidades, migrations, seed de funcionários fixos e 12 períodos mensais.

Sprint 2 — API Backend

Fastify com CRUD de todos os módulos, validação Zod, testes com 80% de cobertura.

Sprint 3 — Frontend Base

React + Vite, identidade WPM, 8 abas, seletor de período, Dashboard e Alunos end-to-end.

Sprint 4 — Módulos Restantes

NPS, Escala, Eventos, Addons, Configurações com backup/export/import. Gestão mensal completa.

Sprint 5 — Deploy

E2E com Playwright, CI GitHub Actions, deploy Vercel (web) + Railway (API) + Neon (banco).

O que o sistema browser-only validou para a próxima fase

34 versões de operação real com a equipe. Todas as regras de negócio foram testadas e refinadas em condições reais. Os bugs encontrados geraram regras permanentes. A próxima fase não começa do zero — começa com um legado funcional sólido, documentado, auditado e avaliado com 9,5/10 por QA sênior.