Files
GTI_GERENCIADOR_FISCAL/docs/superpowers/specs/2026-09-24-fiscal-operational-ui-design.md
T

8.7 KiB
Raw Blame History

GTI Fiscal — painel operacional com drill-down

Objetivo. Refinar as telas atuais Resumo, Agents, Blockers, Jobs e Nova instalação para operação de ~70 clientes, inclusive clientes com 20.000+ produtos. Preservar visual do Gerenciador, stack Jinja/FastAPI/SQLAlchemy e funcionalidades fiscais, Agent, SSO e sincronização existentes. Sem gráficos decorativos, framework frontend novo nem carga de produtos no browser.

Semântica operacional e histórico

Uma expressão SQL compartilhada define OPERATIONALLY_ACTIVE para instalação vinculada a Agent: Tenant.active IS TRUE, Agent.enabled IS TRUE e ausência de enrollment vinculado em estado REVOKED, EXPIRED ou FAILED (estados finais/inativos). Agent legado sem enrollment não é revogado por inferência; clientes LOCAL não são classificados por nome. Installation.processing_enabled=false pausa processamento, não equivale a instalação revogada: ainda pode comunicar heartbeat e indicar indisponibilidade. Nunca excluir registros por nome E2E ou por versão antiga. O registro histórico permanece intacto.

Dashboard usa exclusivamente esta expressão para contagem de saúde, soma de snapshots/cobertura, blockers operacionais, jobs falhos operacionais, versão desatualizada e atenção. Blockers ativos requerem instalação vinculada operacionalmente ativa e resolved_at IS NULL; blockers legados sem instalação e blockers resolvidos permanecem nas listagens históricas. A página Agents usa scope=active por padrão e scope=all para inventário/histórico (com indicação de histórico e badges); Blockers/Jobs usam o mesmo scope para a lista e seus KPIs, preservando filtros adicionais. Um card do Resumo sempre leva à visão scope=active e ao filtro correspondente. O filtro scope=all inclui registros inativos/revogados, e status=RESOLVED em Blockers permite acessar problemas resolvidos. Totais do dashboard e contagens da listagem ativa são reconciliados pela mesma expressão SQL.

Resumo: decisão em um clique

Seis cards <a> completos para Total, Online, Degraded, Offline, Failed, Unknown; destino /agents?scope=active com health=<ENUM> quando aplicável. Labels de apresentação PT-BR: Servidores, Online, Atenção, Offline, Falhou, Não informado. A identidade técnica do filtro permanece na URL e na query SQL. Cobertura: total/completos levam a Agents com ordenação fiscal (visão disponível), bloqueados levam a /blockers?scope=active&status=OPEN, falhas técnicas a /agents?scope=active&health=FAILED, e não classificados a Agents ordenados por pior cobertura. Sem prometer filtros de produto que o sistema não possui. O breakdown CFOP/ST/ICMS/CSOSN/NCM/OTHER liga valores positivos a /blockers?scope=active&status=OPEN&field=<ENUM>; zeros ficam visualmente neutros.

“Atenção necessária” usa até 10 grupos, não 10 linhas cruas: primeiro instalações com falha técnica, depois saúde Failed/Degraded/Offline, grupos de blockers fiscais por instalação/campo/tipo/motivo, versões desatualizadas e outros estados realmente acionáveis. Dentro do grupo fiscal: número de blockers abertos e produtos distintos; agrupar em SQL antes do LIMIT, com ordenação por gravidade e recência. Um grupo oferece link de lista filtrada de blockers ou detalhe de Agent/job. Instalações revogadas, agentes desabilitados, clientes inativos, itens resolvidos ou sem destino operacional não aparecem. Link “Ver todos” abre lista operacional correspondente. Evitar duplicar a mesma instalação como alerta de versão quando um alerta técnico de prioridade maior já a representa; histórico continua nas listas.

Jobs falhos: contagem e lista curta da operação ativa com Cliente, Agent/hostname, tipo, erro truncado, momento e link Ver job para /jobs?scope=active&status=FAILED&job_id=<id>. A página Jobs exibe erro integral quando job_id é informado. Link “Ver jobs” abre status=FAILED. Agents desatualizados: lista compacta em largura suficiente (sem sidebar estreita), cliente/hostname, versão atual/atualização e detalhe do Agent; poucos itens mais “Ver todos” com version=outdated aplicado.

Agents / Servidores

Uma tabela densa, legível em 1366×768 sem scroll horizontal: cliente com instalação/hostname na mesma célula, saúde, fiscal (quantidades resumidas), cobertura, produtos, versão e último contato. Texto secundário só quando existir; badges mostram apenas o valor humano, sem repetir “Saúde técnica:” ou “Status fiscal:”. Busca, saúde (todos os cinco estados), ordenação e scope via GET; chip de filtro ativo e “Limpar filtros”; paginação mantém todos os parâmetros. Link primário visível no cliente/hostname é nativamente acessível por Tab/Enter; clique com mouse na restante da linha abre o mesmo detalhe via delegação pequena em JS, sem eliminar a semântica da tabela. Em telas pequenas, linhas podem assumir apresentação compacta com rótulos por célula, mantendo filtros e ações expostos.

Blockers

KPIs coerentes com scope, status e demais filtros (abertos, produtos/clientes afetados, resultado filtrado), com links apenas quando a métrica tem destino fiel. Breakdown filtrado liga campo positivo ao mesmo conjunto de filtros, trocando só field; filtro selecionado fica visível. Filtros existentes permanecem server-side (cliente, instalação, campo, tipo, status, idade, busca e identificadores existentes), dispostos em uma ou duas linhas no desktop e empilhados no mobile, com “Limpar filtros” retornando à visão ativa padrão.

Tabela destaca código e descrição do produto como link para /blockers/<id>; exibe cliente/servidor, campo, tipo humano, prioridade humana, problema humano, último registro e CTA. Tradutor somente de apresentação mapeia enums conhecidos (BLOCKED_MISSING_EVIDENCE → Evidência fiscal ausente, INVALID_NCM → NCM inválido, prioridades CRITICAL/HIGH/MEDIUM/LOW → Crítica/Alta/Média/Baixa) e cai em rótulo legível para desconhecidos; o detalhe mantém o código técnico original. Paginação limitada (50), consulta com COUNT separado, sem dropdown de produtos nem N+1.

Jobs

Atalhos compactos para PENDING, RUNNING, COMPLETED, FAILED, todos filtrando scope=active e mostrando a seleção. Status PT-BR: Pendente, Executando, Concluído, Falhou; tipos conhecidos (SYNC_INCREMENTAL, INITIAL_SYNC, REPROCESS_ALL, REPROCESS_PRODUCTS) ganham labels humanos. A lista agrupa cliente e servidor, depois tipo, status, criado/finalizado, duração e erro curto. Erro integral e enum técnico aparecem na vista filtrada job_id da própria página, sem criar uma tela artificial. Seleção de scope histórico e “Limpar filtros” mantêm os demais parâmetros úteis. Não acionar jobs, somente leitura do banco.

Estilo, acessibilidade e escala

Usar somente central/static/control-panel.css sobre os tokens imutáveis gti-theme.css. Estados semânticos: sucesso verde, atenção amarelo, falha vermelha, histórico/desconhecido cinza, bloqueio fiscal laranja. Foco visível, navegação Tab/Enter e Space nos controles apropriados, links <a> em cards; nenhum div simulando botão. Mobile 375 px preserva busca e ações, desktop 1366×768 e 1920×1080 aproveitam largura sem blocos de vazio. Testar light/dark por screenshot, não só inspecionando tokens. Combobox de clientes ativos da Nova instalação permanece com busca nome/CNPJ, mouse/teclado, client_id hidden e validação server-side; só retoque estético se necessário.

Queries devem usar agregados e grupos SQL, bounded LIMIT, COUNT e paginação server-side; não carregar listas de produtos/snapshots inteiros nem emitir uma consulta por item. Medir número de queries do dashboard e inspecionar planos quando filtros/campos precisarem de índice. Se necessário, migration de índices pequena e reversível; nunca mudar engine fiscal ou dados históricos. Regressões confirmam exclusão de inativos/revogados, coerência card→querystring→resultado, agrupamento, labels, paginação e query count/ausência de N+1.

Validação e deploy

Rodar suites existentes e regressões focadas. Browser smoke em Resumo, Agents, Blockers, Jobs, Nova instalação; navegar Resumo→Online/Total/NCM/Jobs falhos/Agent desatualizado e voltar; verificar light/dark nos viewports 1920×1080, 1366×768, 375 px e Tab/Enter/Space. Nova instalação não deve criar registros no smoke. Usar exclusivamente scripts/deploy_hub.ps1 para deploy/backup/migration/rollback/health, sem SSH improvisado nem scripts paralelos. Verificar health público e métricas operacionais pós-deploy. Se autenticação visual do Gerenciador não estiver disponível, reportar explicitamente o bloqueio em vez de alegar screenshot de produção.