---
name: sankhya-dashboard-html-jsp-custom-best-pratices
description: "This skill should be used when the user asks for patterns, best practices, creation, or fixing of Sankhya dashboards using HTML, JSP, Java, and SQL."
category: code
risk: safe
source: community
tags: [sankhya, dashboard, jsp, html, sql, best-practices]
date_added: "2026-03-10"
---
# sankhya-dashboard-html-jsp-custom-best-pratices
## Purpose
To provide a consolidated guide of patterns and best practices for creating and maintaining dashboards, SQL queries, BI parameterization, and UI/UX within the Sankhya ecosystem (JSP/HTML/Java).
## When to Use This Skill
This skill should be used when:
- The user asks about "boas praticas do sankhya" or "Sankhya best practices".
- The user mentions "dashboard sankhya" or is working on a Sankhya BI dashboard.
- The user asks for anything related to the word "Sankhya".
- The user wants to create or modify code files for Sankhya dashboards.
## Core Capabilities
1. **Code Generation & Review**: Apply JSP/JSTL patterns and server-side organization to reduce compilation errors and rendering failures.
2. **Visual Consistency**: Standardize visual identity in BI components using predefined CSS tokens.
3. **Database Exploration**: Structure data exploration queries for performance and correct mapping of Sankhya entities.
4. **BI Construction Guide**: Use the HTML5 component flow in BI to ensure correct rendering, reactivity, and navigation.
## Patterns
### Melhores Práticas de Código
Aplicar padrões de JSP/JSTL e organização server-side para reduzir erros de compilação, falhas de renderização e regressões em dashboards/telas.
**Diretrizes de implementação**
- Declarar diretivas JSP e taglibs obrigatórias no topo do arquivo.
- Forçar `isELIgnored="false"` para habilitar `${...}` em tempo de renderização.
- Preferir `core_rt` para JSTL core no ecossistema Sankhya.
- Evitar scriptlets Java em JSP; usar JSTL (`c:if`, `c:choose`, `c:forEach`).
- Modularizar lógica de negócio (camadas/serviços), evitando acoplamento em arquivo único.
- Evitar hardcode de credenciais, URLs sensíveis e tokens.
- Modelar estado global da UI (dados, filtros, ordenação, aba ativa) e resetar estado antes de novo carregamento.
- Persistir preferências de visualização no `localStorage` (ordem de colunas e ordenação).
- Implementar carregamento sob demanda para abas/modais pesados (lazy-load) para reduzir tempo inicial.
- **Blindagem de Parâmetros**: Sempre definir um valor padrão (fallback) para parâmetros de URL via `c:set` para evitar Erro 500 no servidor Java do Sankhya.
- **Separação de Camadas (JSP vs JS)**: Evitar injetar tags JSP diretamente dentro de blocos `
```
**Consumo seguro de `snk:query`**
- Iterar em `query.rows` (não no objeto raiz).
- Testar vazio com `empty query.rows`.
```jsp
SELECT CAB.NUNOTA, CAB.CODPARC
FROM TGFCAB CAB
Sem resultados
${linha.NUNOTA}
```
**Sanitização de parâmetros antes da SQL**
- Normalizar valor de entrada.
- Remover aspas (`"` e `"`) antes de injetar em query.
- Definir fallback seguro para evitar SQL inválida.
```jsp
SELECT CODUSU, NOMEUSU
FROM TSIUSU
WHERE CODUSU = :codusu_seguro
```
**Estado de tela e lazy-load em dashboard único**
- Definir listas globais para reutilização em KPI, gráfico, tabela e modais.
- Guardar flag de carregamento por aba para evitar reconsultas desnecessárias.
- Recarregar dados e reabrir o contexto (produto/aba) após atualização transacional.
```js
var dadosGlobais = [];
var produtoAtual = null;
var abaCarregada = {};
function abrirDetalhe(dado) {
produtoAtual = dado;
abaCarregada = {};
trocarAba("estoque");
}
function trocarAba(aba) {
if (aba === "estoque" && !abaCarregada.estoque) carregarAbaEstoque(produtoAtual.CODPROD);
if (aba === "pedidos" && !abaCarregada.pedidos) carregarAbaPedidos(produtoAtual.CODPROD);
if (aba === "parceiros" && !abaCarregada.parceiros) carregarAbaParceiros(produtoAtual.CODPROD);
}
```
**Exemplo de Blindagem e Separação de Camadas**
```jsp
<%-- 1. Blindagem no topo do arquivo --%>
<%-- 2. Container oculto para dados (Separação JSP vs JS) --%>
```
### Identidade Visual (Colors)
Padronizar identidade visual em componentes BI para consistência entre gadgets HTML5, tabelas e indicadores.
**Diretrizes de UI/UX**
- Definir paleta via tokens (`--color-*`) para evitar valores espalhados.
- Priorizar contraste mínimo entre texto/fundo (legibilidade operacional).
- Manter semântica visual consistente: sucesso, alerta, erro, neutro.
- Permitir sobrescrita por dados vindos do SQL (`BKCOLOR`, `FGCOLOR`) quando necessário.
- Usar cabeçalho sticky e colunas fixas para tabelas largas com alto volume de leitura.
- Diferenciar status de linha via classes CSS (aprovado, parcial, histórico, crítico) para leitura operacional rápida.
> Os nomes de tabelas e campos abaixo são representativos e podem variar conforme a implementação da instância.
```html
```
```sql
SELECT
V.CODMETA,
V.VALOR_ATUAL,
V.VALOR_META,
CASE WHEN V.VALOR_ATUAL >= V.VALOR_META THEN '#1A7F37' ELSE '#B42318' END AS BKCOLOR,
'#FFFFFF' AS FGCOLOR
FROM AD_DADOS_VENDA V
```
```html
```
### Consultas e Exploração de Banco
Estruturar exploração de dados com foco em performance, legibilidade e mapeamento correto de entidades Sankhya.
**Boas práticas de exploração (DBExplorer)**
- Usar DBExplorer para inspeção de tabelas, campos, índices, views e procedures.
- Respeitar limite de retorno configurado (ex.: `DBEXPMAXROW`) para evitar carga excessiva.
- Evitar `SELECT *` em tabelas com campos volumosos (BLOB/CLOB).
**Mapas essenciais do ecossistema**
- Dicionário: `TDDTAB`, `TDDCAM`, `TDDOPC`, `TDDINS`, `TDDLIG`.
- Comercial/financeiro: `TGFCAB`, `TGFITE`, `TGFTOP`, `TGFPAR`, `TGFPRO`, `TGFEST`, `TGFVAR`.
- Segurança/acesso: `TSIUSU`, `TSIGRU`, `TSIACI`, `TSIIMP`.
**Padrões de SQL recomendados**
- Em TOP versionada, relacionar `CODTIPOPER` + data de alteração (`DHTIPOPER`/`DHALTER`).
- Em filtros opcionais, usar padrão `(... = :P_PARAM OR :P_PARAM IS NULL)`.
- Parametrizar sempre (evitar literals de usuário).
> Os nomes de tabelas e campos abaixo são representativos e podem variar conforme a implementação da instância.
```sql
SELECT
CAB.NUNOTA,
CAB.CODPARC,
CAB.DTNEG,
ITE.SEQUENCIA,
ITE.CODPROD,
(ITE.VLRTOT - ITE.VLRDESC) AS VLR_LIQUIDO
FROM TGFCAB CAB
JOIN TGFITE ITE
ON ITE.NUNOTA = CAB.NUNOTA
JOIN TGFTOP TOP
ON TOP.CODTIPOPER = CAB.CODTIPOPER
AND TOP.DHALTER = CAB.DHTIPOPER
WHERE (CAB.CODPARC = :P_CODPARC OR :P_CODPARC IS NULL)
AND (CAB.CODVEND = :P_CODVEND OR :P_CODVEND IS NULL)
```
```sql
SELECT
U.CODUSU,
U.NOMEUSU,
G.NOMEGRUPO,
A.CODREL,
I.NOME AS DESCRICAO_RECURSO,
A.CONS,
A.ALTERA
FROM TSIUSU U
JOIN TSIGRU G ON G.CODGRUPO = U.CODGRUPO
JOIN TSIACI A ON A.CODGRUPO = U.CODGRUPO
JOIN TSIIMP I ON I.CODREL = A.CODREL
WHERE U.CODUSU = :P_CODUSU
ORDER BY I.NOME
```
### Guia do Construtor de BI
Aplicar fluxo de desenvolvimento de componentes HTML5 no BI para garantir renderização, reatividade e navegação entre níveis.
**Estrutura e publicação**
- Empacotar componente em `.zip` com `index.html` como entrada principal.
- Organizar recursos estáticos em `assets/` (CSS, JS, libs, imagens).
- Usar XML/design conforme necessidade; considerar JSP de entrada quando houver pré-processamento server-side.
**Fluxo de dados e parâmetros**
- Definir variáveis SQL ou BeanShell conforme complexidade.
- Usar prefixos de tradução de parâmetro:
- `:` para bind padrão.
- `:#` para substituição literal (avaliar com cautela e validação).
- `:@` para literal textual em cenários como `LIKE`.
- Em parâmetros multi-list extensos, usar `/*inCollection*/`.
> Os nomes de tabelas e campos abaixo são representativos e podem variar conforme a implementação da instância.
```sql
SELECT
C.CODCID,
C.NOMECID,
C.UF
FROM AD_TABELA_EXEMPLO C
WHERE /*inCollection*/ C.CODCID IN :P_CODCID /*inCollection*/
```
**Reatividade e ciclo de vida**
- Programar re-render quando filtros globais mudarem.
- Evitar dependência exclusiva de `DOMContentLoaded` em conteúdo injetado.
- Aplicar inicialização assíncrona para garantir elementos disponíveis.
```html
```
**Drill-down e eventos**
- Modelar níveis independentes (macro → micro) com argumentos explícitos.
- Evitar contêiner vazio em níveis subsequentes.
- Usar herança de contexto entre níveis para preservar filtros e navegação.
- Implementar ações de clique para atualizar detalhes e abrir telas nativas com chave de contexto.
**Navegação multi-nível (openLevel e contrato de contexto)**
- Definir constantes de nível em configuração (`NIVEL_RESUMO`, `NIVEL_DETALHE`, `NIVEL_ITEM`) para evitar acoplamento em string solta.
- Encapsular `openLevel` em funções dedicadas por rota de navegação (ex.: abrir detalhe por vendedor, abrir itens por parceiro).
- Repassar parâmetros de contexto entre níveis com contrato explícito (`ARG_*` para chaves e `P_*` para filtros/período).
- Validar disponibilidade de `openLevel` e parâmetros obrigatórios antes de navegar.
- Aplicar fallback de erro no console/UI quando o contexto não permitir abertura de nível.
```js
var cfg = window.DASH_CONFIG || {};
var NIVEL_DETALHE = cfg.NIVEL_DETALHE || "NIVEL_B";
var NIVEL_ITEM = cfg.NIVEL_ITEM || "NIVEL_C";
function abrirNivelDetalhe(codigoEntidade) {
if (!codigoEntidade || typeof openLevel !== "function") return;
openLevel(NIVEL_DETALHE, {
ARG_CODENT: parseInt(codigoEntidade, 10),
P_PERIODO_INI: cfg.P_PERIODO_INI || "",
P_PERIODO_FIN: cfg.P_PERIODO_FIN || "",
P_CODMETA: cfg.P_CODMETA || ""
});
}
function abrirNivelItem(codigoEntidadeFilha) {
if (!codigoEntidadeFilha || typeof openLevel !== "function") return;
openLevel(NIVEL_ITEM, {
ARG_CODENT_FILHA: parseInt(codigoEntidadeFilha, 10),
P_PERIODO_INI: cfg.P_PERIODO_INI || "",
P_PERIODO_FIN: cfg.P_PERIODO_FIN || "",
P_CODMETA: cfg.P_CODMETA || ""
});
}
```
**Segurança e bloqueio de acesso por escopo**
- Restringir qualquer consulta de nível pela relação usuário-meta/escopo antes de agregar dados.
- Centralizar o predicado de segurança em função de montagem de `WHERE` para reaproveitamento em KPIs, grids e gráficos.
- Preferir variáveis de sessão (`CODUSU_LOG` ou função equivalente de usuário logado) para evitar spoof de parâmetro de usuário.
- Bloquear carga quando parâmetros críticos estiverem ausentes (ex.: período, meta, entidade de drill-down).
> Os nomes de tabelas e campos abaixo são representativos e podem variar conforme a implementação da instância.
```sql
SELECT
M.CODMETA,
M.CODENTIDADE,
SUM(M.VLRPREV) AS VLR_PREV,
SUM(M.VLRREAL) AS VLR_REAL
FROM AD_DADOS_META M
WHERE M.CODMETA = :P_CODMETA
AND M.DTREF BETWEEN TO_DATE(:P_PERIODO_INI, 'DD/MM/YYYY')
AND TO_DATE(:P_PERIODO_FIN, 'DD/MM/YYYY')
AND EXISTS (
SELECT 1
FROM AD_META_USUARIO_LIB L
WHERE L.CODMETA = M.CODMETA
AND L.CODUSU = STP_GET_CODUSULOGADO
)
GROUP BY M.CODMETA, M.CODENTIDADE
```
**Grid hierárquica com expansão/colapso**
- Estruturar mapa `filhosPorPai` e estado `nosExpandidos` para renderização incremental da árvore.
- Inicializar nós não analíticos de níveis superiores como expandidos para melhorar leitura inicial.
- Em nós colapsados, exibir agregados de descendentes analíticos para manter contexto sem abrir toda árvore.
- Fornecer ações rápidas de “Expandir tudo” e “Recolher tudo” no cabeçalho.
- Em filtros de texto, incluir ancestrais dos nós encontrados para preservar rastreabilidade hierárquica.
```js
var filhosPorPai = {};
var nosExpandidos = {};
function alternarNo(codNo) {
var id = String(codNo);
nosExpandidos[id] = !nosExpandidos[id];
renderizarGrid();
}
function obterVisiveis(raiz) {
var lista = [];
function visitar(pai) {
(filhosPorPai[pai] || []).forEach(function (no) {
lista.push(no);
if (nosExpandidos[String(no.CODNO)]) visitar(String(no.CODNO));
});
}
visitar(String(raiz || ""));
return lista;
}
```
**Resiliência de carregamento**
- Separar a carga principal da carga complementar (ex.: realizado mensal) e não bloquear a visualização principal por falha secundária.
- Tratar ausência de dados por componente (`vazio`) sem derrubar o layout inteiro.
- Destruir instâncias de gráfico antes de recriar para evitar vazamento e sobreposição visual.
- Carregar painéis secundários somente ao abrir aba/visão correspondente (on-demand).
**Navegação intra-nível (single JSP)**
- Tratar o JSP único como shell de navegação: tabela principal + modal de detalhe + abas internas + modais auxiliares.
- Encadear cliques sem trocar de nível Sankhya: KPI → lista modal, gráfico → filtro de tabela, linha da tabela → detalhe.
- Aplicar atalhos de ação no detalhe para abrir cadastro nativo no contexto da chave primária.
- Fechar modal por clique no overlay para reduzir atrito de uso.
```js
function abrirTelaNativa(resourceIdBase64, pkObj) {
var pk = btoa(JSON.stringify(pkObj));
top.location.href = "/mge/system.jsp#app/" + resourceIdBase64 + "/" + pk + "&pk-refresh=" + Date.now();
}
function onKpiClick(lista) {
abrirModalLista("Itens selecionados", "Navegação por atalho", lista);
}
function onGraficoClick(grupo) {
filtrarTabelaPorGrupo(grupo);
}
```
**Feedback operacional de interface**
- Exibir estados explícitos de carregamento, vazio e erro em cada painel.
- Em ações de atualização, desabilitar botão de confirmação até o retorno do `executeQuery`.
- Após sucesso, recarregar dados e restaurar contexto anterior (produto e aba ativa).
**Variáveis internas de segurança**
- Aproveitar variáveis de sessão para segurança em nível de linha (`CODUSU_LOG`, `CODGRU_LOG`, `CODVEN_LOG`).
- Restringir dados por contexto do usuário antes de montar visualizações.
## Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.