Visão Geral
Leitura do portfólio: indicadores, mapa orbital dos setores e ranking por nota de prioridade.
Próximos marcos
Todos os projetos em andamento · ordenado por dataProjetos do setor
Projetos aguardando análise e aprovação
Integrações com softwares externos utilizadas nos projetos
Assuntos de reunião que ainda não são projetos formais — defina um responsável e prazo para resolver
| Assunto | Equipe | Responsável | Criada em | Data prevista | Status | Ações |
|---|
| Arquivo | Tipo | Anotação | Tamanho | Enviado em | Ações |
|---|
| Assunto | Excluída em | Ações |
|---|
Bases em construção
Fontes de dados que vão alimentar a pirâmide, ainda em levantamento com os responsáveis.
Central de alertas
Central de decisões
Impacto em cascata
AI Master
Camada cognitiva que consolida a leitura de todos os setores. Não substitui a pirâmide — apenas enxerga a empresa como um todo. Respostas pré-definidas para demonstração.
| Nome | Setor | Responsável Técnico | Saúde | Checklist go-live | Ações |
|---|
Indicadores do banco que sustenta as aplicações do I&T — tamanho, crescimento, saúde e adoção por setor
pg_database_size, pg_stat_*) por RPC restrita a Administradores — nada aqui passa pela Management API do Supabase, então não há token envolvido.
A série histórica é gravada 1x por dia pelo pg_cron: o gráfico só ganha forma depois de alguns dias de coleta.
A adoção por setor vem da auditoria de acesso ao painel, agregada por hora e derivada do cadastro do DP — não é medição de quem consulta o banco por fora desta aplicação.
Serviços do Supabase
Estado de cada serviço gerenciado e uso de infraestrutura
Cobertura por setor
Quantas pessoas de cada setor já têm acesso ao painel. Cobertura não é adoção: mede quem pode entrar, não quem entra.
Aplicações por setor
Distribuição do diretório Links GVS — quais áreas já têm sistema próprio no portfólio do I&T
Disponibilidade das aplicações
Uptime e tempo de resposta de cada página/sistema do diretório Links GVS
| Aplicação | Setor | Uptime | Resposta média | Faixa (mín–máx) | Última checagem |
|---|
Crescimento do banco
Tamanho total ocupado, por dia de coleta
Ocupação por schema
Quanto cada área do banco representa do total
Adoção por setor
Setores que acessaram o painel no período
Telas mais acessadas
Onde as pessoas passam o tempo dentro do painel
Maiores tabelas
Tamanho em disco, volume estimado e sinais de uso. Seq. = varreduras sem índice; Mortas = tuplas aguardando vacuum.
| Schema | Tabela | Tamanho | Linhas | Mortas | Seq. | Índice |
|---|
Consultas mais lentas
Média de execução, via pg_stat_statements. O painel some quando a extensão não está habilitada no projeto.
| Consulta | Chamadas | Média | Total |
|---|
Gerencie quem tem acesso ao painel
Principais decisões e convenções de desenvolvimento deste app — pra manter consistência entre sessões e pessoas diferentes mexendo no código
Design visual
- CSS puro com variáveis em
:root— sem Tailwind, Bootstrap ou qualquer framework de UI. - Nunca usar cor fixa (hex) num componente novo — sempre um token semântico (
var(--surface-card),var(--text-body),var(--action-accent),var(--border-default)), pra funcionar nos dois temas automaticamente. Os nomes antigos (--card-1,--line-cyan…) viraram apelidos destes: valem, mas não em código novo. - Fundo tingido é
color-mix(in srgb, var(--cor) var(--status-soft), transparent). Concatenar alfa numvar()—var(--purple)22— não é cor válida e simplesmente não pinta: foi assim que as pílulas de status ficaram meses sem fundo. - Tamanho de fonte vem da escala
--fs-2xsa--fs-kpi, não de um número escolhido na hora. - Tema claro é o padrão (
:root); o escuro é um override em:root[data-theme="dark"]. - Fonte é
system-ui(a fonte do sistema operacional) — não é Inter nem nenhuma outra importada. - Regras completas (paleta, tipografia, padrão de card/tabela/aba) estão na skill
gestão-visual, consultada antes de qualquer alteração visual.
Deploy e ambiente
- Sem build step — é um
index.htmlpuro. Deploy é automático: todo push no branchmainpublica em produção (Vercel → tecnologia.grupogvs.com.br). - Por isso, testar local antes de subir —
node scripts/static-server.mjs, comsupabase-config.jsrenomeado pra testar em modo mock quando fizer sentido. - Migração de banco (SQL) nunca é automática — sempre aplicada manualmente no SQL Editor do Supabase, combinada antes com quem administra o banco.
- Nunca fazer deploy de um
select/escrita que dependa de uma coluna nova sem confirmar que a migração já rodou em produção — coluna faltando quebra a busca inteira e derruba o app pro modo mockup (já aconteceu).
Banco de dados / Supabase
- Schema principal é
gestao_projetos— todas as tabelas da aplicação vivem lá, com RLS habilitado em toda tabela. departamento_pessoalé de outro sistema (RH) — acesso é só leitura (setores, colaboradores, equipes), nunca escrita.- Scripts de manutenção usam o usuário
app_tecnologia_rw(permissões restritas por schema) — nunca o usuáriopostgres(super-usuário). - Antes de confiar que uma coluna nova funciona no front, testar direto na API REST do Supabase (com o header
Accept-Profile) pra confirmar que ela já existe em produção.
Segurança
- Segredos (
.env.supabase, chaves de serviço) nunca são commitados — ficam no.gitignoree é assim que continua. - A chave pública (anon) em
supabase-config.jspode ser versionada — a segurança vem das políticas de RLS, não do sigilo dessa chave. - Dois perfis de usuário: Administrador (edita) e Solicitante (só visualiza/sugere) — a checagem de permissão sempre existe também no banco (RLS), nunca só escondendo um botão no front.
- Qualquer alteração de schema é revisada quanto ao impacto nas políticas de RLS já existentes antes de aplicar.
Lições da revisão do Supabase (02/09/2026)
Revisão geral do banco em 02/09/2026 — cinco frentes de leitura (advisors de segurança e performance, segurança medida no banco, integridade estrutural e inventário contra o Atlas de 26/08). Resultado: 364 objetos, 1.405 MB, 3,38 milhões de linhas — crescimento de 53% em uma semana, com 3 schemas inteiros criados fora de migration. As regras abaixo são o que a revisão virou em convenção de desenvolvimento; valem para qualquer aplicação do Grupo que use este banco, não só para esta.
O que toca esta aplicação agir
- O schema
gestao_projetostemanoncom USAGE, SELECT em 17 objetos e INSERT/UPDATE/DELETE concedidos em 16 tabelas. Hoje só uma policy o alcança — umcreate policy … to publicdistraído abre o resto. Grant sem policy não é segurança: revogar o grant, não confiar na ausência de policy. - 5 views daqui são
security_invoker = offcom donopostgres— rodam como superusuário e ignoram a RLS das tabelas de baixo (uma delas expõe dado de RH até paraanon). Toda view nova nasce comsecurity_invoker = on. - O INSERT público em
ideias_externas_pendentes(e-mail, telefone, arquivo) não tem limite — precisa de rate limit ou captcha na borda antes de virar problema. - 23 tabelas deste schema estão vazias — estrutura criada e nunca usada. Tabela sem dono declarado e sem uso deve ser removida, não mantida "por garantia".
Storage e arquivos corrigido 03/09
- Havia 6 buckets públicos com 21.211 objetos, quatro deles aceitando upload, sobrescrita e exclusão pela chave pública (que viaja no JavaScript). Corrigido em 03/09: escrita anônima derrubada e os quatro buckets fechados.
- Regra que ficou: bucket com dado de pessoa nunca é público, e nenhuma policy de escrita aponta para
anon/public— escrita é sempreauthenticatedno mínimo. - Exibir arquivo no front é com
createSignedUrl(), nuncagetPublicUrl()— URL pública em bucket privado quebra a tela e URL pública em bucket aberto vaza o acervo. - Script de correção pronto e não aplicado é risco aberto: pendência de segurança tem prazo, não gaveta (esse ficou 4 dias parado).
RLS e policies alto
- 83 das 193 policies do banco têm
qual/with_checkigual atrue— em um schema isso significa 23 tabelas comALL trueparaauthenticated, ou seja, qualquer login apaga cadastro com CPF e a própria auditoria. - "Autenticado" não é "funcionário": 187 contas, 34 domínios distintos, 150 por senha, nenhuma com MFA. Policy nunca é escrita assumindo que quem logou é do time.
ALL … truenão é policy — é RLS desligada com passo extra. Separar leitura de escrita e amarrar a escrita ao dono da linha.- 79 tabelas têm RLS ligada e nenhuma policy ("RLS decorativa") — em schema exposto isso engana quem revisa: ou entra policy, ou entra revoke.
- Grant em tabela cujo schema não tem USAGE é armadilha, não proteção: inalcançável hoje, aberto no dia em que alguém conceder o USAGE.
Funções, views e integrações alto
- Toda função
security definertemsearch_pathfixo — 36 das 37 têm; a única sem é justamente a que manda dado para fora. - Integração externa só por HTTPS. A revisão encontrou um trigger enviando lead com CPF, e-mail, telefone e endereço por HTTP sem TLS a um host externo, a cada insert/update/delete — exfiltração em claro, por desenho.
- Integração que sai do banco precisa de dono declarado e motivo escrito: ninguém sabia por que aquele trigger existia, e isso trava a correção.
- 51 funções em
corecomsearch_pathmutável são dívida nossa, não de terceiro — função nova já nasce com osearch_pathfixo.
Credenciais e acessos alto
- Três credenciais de aplicação leem 77 tabelas de
coremais outros quatro schemas: vazar a senha de um app pequeno vaza a base de clientes inteira. Cadaapp_*_rwsó nos schemas do seu sistema. - Roles com login e zero grant são resíduo — apagar, não deixar "para o caso de".
- Auditoria contada por papel sem
bypassrlsdevolve 0 onde há dado (aconteceu em 34 tabelas). Script que "conta o banco" roda por credencial com leitura total, senão o relatório mente. - MFA para administradores e proteção contra senha vazada estavam desligadas — requisito, não opcional.
Migration, estrutura e dado dívida
- Nada de objeto fora de migration versionada: nasceram 3 schemas e 91 objetos sem registro em
supabase_migrations. Nasceram bem modelados — e ainda assim invisíveis para quem vem depois. - Clonar tabela entre schemas é proibido. Um clone de 19 tabelas em
publicfoi desfeito e voltou no mesmo dia, com RLS desligada — duplicidade sempre volta se ninguém apagar a causa. - Normalização não converte NULL em string vazia — 19.064 linhas de uma tabela de staging viraram
'', e vazio que passa por valor esmaga registro no join. Vale também para NBSP (chr(160)) e lixo de Excel (#VALUE!), quebtrimnão pega. - Toda FK tem índice na coluna filha (127 estão sem) e toda tabela de schema canônico tem PK.
- Índice que ninguém usa é custo de escrita: 20 índices nunca usados somam 180,8 MB, um deles 112,9 MB sozinho.
- Contagem de usuário só vale com recorte de uso: os "147 usuários ativos" da regra da casa são 147 cadastrados e cerca de 12 com login em 30 dias.
Fluxo de dados — Query de Instalações (GVOEM)
Tabela central: gvoem.instalacoes — todos os LEFT JOINs partem dela (direta ou indiretamente). Arraste os cards pra reorganizar; as linhas se ajustam sozinhas.
fonte → fonte_geracao JOIN: u.id = i.id_usina
uf → uf JOIN: e.id = spe.id_uau
- Tudo parte de instalacoes (LEFT JOIN preserva a instalação mesmo sem correspondência nas outras tabelas).
- Usina, distribuidora, consórcio, titular e SPE são ligados diretamente por chaves estrangeiras dentro de instalacoes.
- A partir da SPE a query "encadeia" mais dois caminhos: SPE → Cluster → Holding (hierarquia societária) e SPE → Empresa/UAU (cidade, uf da localização).