Sistema Mestre — Manual de Operação
Vértice Health Platform

Sistema Mestre

Como o ecossistema funciona, como fazer a engrenagem girar sem computador ligado, como criar novos clientes e como manter tudo saudável.

🌐
Como o Ecossistema Funciona
Arquitetura geral — o que existe e onde fica
GitHub (main)
→
GitHub Actions
→
Hostinger
Eriane + Vértice Core
+
Supabase
por cliente
Repositório
vertice-health-platform
GitHub: vertice-health/vertice-health-platform
Branch único: main
Local: D:\vertice\platform\vertice-health-platform
Isolamento total
Cada cliente = ecossistema próprio
Supabase próprio · Gemini próprio · Domínio próprio · Chaves próprias. Zero dados compartilhados entre clientes.
Stack
HTML · Supabase · Gemini
Frontend: HTML5 + CSS3 + JS ES6+ vanilla (sem frameworks)
Backend: Supabase (Auth + DB + Storage + Edge Functions)
IA: Gemini 2.5 Flash via gemini-proxy Edge Function
Deploy: SCP/rsync para Hostinger via GitHub Actions
Estrutura de pastas
Onde fica o quê
apps/admin/ → Painel Vértice
apps/master/ → Painel médico
apps/tenant/ → Área paciente
apps/client/ → Painel secretaria
core/ → Auth, Supabase, UI
modules/ → Repos + presets
clientes/ → Instâncias por cliente
supabase/ → Patches SQL
scripts/ → Automações Node.js
🤖
Processos Automáticos
Tudo que roda sem o computador ligado — GitHub Actions na nuvem
✅
O computador não precisa estar ligado. Todos os deploys, testes e health checks rodam na nuvem via GitHub Actions. O único momento que precisa de computador é para fazer git push (commitar uma mudança).
Workflow Gatilho O que faz Destino
deploy-eriane-faria.yml Push em clientes/eriane-faria/** ou core/** Faz rsync de clientes/eriane-faria/ para o servidor. Verifica HTTP 200 após deploy. draerianefaria.com.br
82.25.67.107:65002
deploy-vertice-core.yml Push em apps/admin/** Faz rsync de apps/admin/ para o servidor. Exclui vertice.config.json. core.vertice-ecossistema.com.br
82.180.153.142:65002
health-check.yml Cron: todo hora (0 * * * *) Verifica HTTP dos sites. Salva snapshot em client_health_snapshots no vertice-admin. Envia e-mail se offline. Supabase vertice-admin
wddojycpndvatvqtpiwt
playwright.yml Push em tests/** ou dispatch manual Roda 25+ testes Playwright: auth, roles, redirects, secretaria, funcional, unidade. GitHub (sem deploy)
lint.yml Push em core/**, modules/** Roda ESLint + Prettier check nos arquivos JS do core. GitHub (sem deploy)
⚠️
Deploy atrasado ou falhando? O GitHub Actions pode atrasar ou falhar silenciosamente. Sempre confirme via SSH ou verificando o HTTP do site após um push importante. Se falhar, use o deploy manual na seção abaixo.
✦
Criar Novo Cliente
Fluxo completo do zero até produção
ℹ️
Pré-requisito: Cliente precisa ter um projeto Supabase criado (com ref e PAT). NUNCA criar projeto na conta lcunhapereira@gmail.com — usar e-mail próprio do cliente ou criar conta nomeclinica.vertice@gmail.com.
1
Preencher formulário de onboarding
Acesse Onboarding no menu lateral → preencha os 5 passos (empresa, marca, plataforma, plano, revisão) → submeta. O sistema salva em clientes_admin com status implementacao.
2
Step 6 — Gerar e executar o comando de provisionamento
Após o submit, o onboarding avança para o Step 6. Preencha: Supabase Ref + PAT + cores. Clique Gerar Comando e copie o comando gerado. Execute no PowerShell local:
node scripts/provisioning/tenant.js \ --slug joao-silva \ --nome "Dr. João Silva" \ --especialidade "Cardiologia" \ --ref xsffqlbpiwzxkxakjgmb \ --pat sbp_xxxx \ --cor-primaria "#1B3A6B" \ --cor-acento "#C0392B" \ --host 82.25.67.107 --port 65002 \ --ssh-user u707423342 \ --remote-path "/home/u707423342/domains/joao.com.br/public_html"
O script executa 4 etapas: estrutura de arquivos → schema SQL → deploy SSH → ativação. Monitorável via Monitorar progresso no Step 6.
3
Aplicar módulo específico (se cardiologia, etc.)
Para especialidades com schema extra (ex: cardiologia), aplicar o SQL do módulo:
node scripts/provisioning/schema.js \ --ref REF --pat sbp_xxx \ --file supabase/modules/cardiologia.sql
4
Preencher anon_key no config.json e criar usuário médico
Após provisionar, preencher clientes/[slug]/config.json com a anon_key do Supabase. Criar o usuário médico no Supabase Auth (GoTrue Admin API, não SQL direto). Nunca commitar config.json.
5
Verificar e ativar
Rodar .\scripts\verificar-cliente.ps1 -cliente joao-silva para confirmar que logo, favicon, config e tema.css estão corretos. O tenant.js já atualiza clientes_admin.status = 'ativo' automaticamente.
🚀
Deploy Manual
Quando o GitHub Actions atrasa ou falha — executar do computador
Admin Vértice
core.vertice-ecossistema.com.br
# PowerShell — envia todos os HTML do admin scp -P 65002 -i ~/.ssh/hostinger_key -o StrictHostKeyChecking=no ` apps/admin/*.html ` u627878224@82.180.153.142:/home/u627878224/domains/vertice-ecossistema.com.br/public_html/core/
Manual via SCP
Dra. Eriane Faria
draerianefaria.com.br
# PowerShell powershell -ExecutionPolicy Bypass -File scripts\deploy.ps1 -cliente eriane-faria
Manual via deploy.ps1
Dr. Carlos (demo)
core.vertice-ecossistema.com.br/carlos-mendes
# Python com paramiko python scripts/deploy-carlos-demo.py
Manual via Python
Novo cliente
Qualquer domínio Hostinger
# Node.js — SSH nativo node scripts/provisioning/deploy.js ` --slug joao-silva ` --host 82.xx.xx.xx ` --user uXXXXXX ` --remote /home/.../public_html
Automático via tenant.js
🔑
Chave SSH: ~/.ssh/hostinger_key — funciona para Eriane (82.25.67.107) e Core Vértice (82.180.153.142). Para servidores de novos clientes, precisará adicionar a chave pública no ~/.ssh/authorized_keys do servidor.
🗄️
Banco de Dados
Patches SQL, como aplicar, o que existe onde
⚠️
Regra de ouro: Patches são numerados sequencialmente (001, 002…) e NUNCA alterados após aplicação. Para corrigir, criar um novo patch. Sempre confirmar qual projeto Supabase está selecionado antes de rodar.
📋
Aplicar patch SQL em qualquer cliente
node scripts/provisioning/schema.js \ --ref fwqjelwrayxqnxnzlxxj # ref do projeto --pat sbp_xxx # PAT do projeto --file supabase/patch-041-ai-usage-log-anon-select.sql
📋
Criar novo patch
Criar arquivo em supabase/patch-NNN-descricao.sql com o próximo número. Rodar via schema.js. Commitar o arquivo no Git. O patch só vai para o banco via execução manual — não é automático.
Patches importantesAplica emO que cria
schema.sqlQualquer novo cliente18 tabelas base: usuarios, pacientes, consultas, prontuarios…
patch-033Clientes (eriane, carlos)tenant_config, tenant_theme, tenant_modules (config no banco)
patch-034Clientesai_cache — cache de respostas Gemini por 24h
patch-035Clientesai_usage_log — log de chamadas IA (latência, cache, erro)
patch-036vertice-adminclient_health_snapshots — pings horários do health-check
patch-037Clienteserror_log — captura window.onerror do JS em produção
patch-040vertice-adminprovisioning_log — rastreio do provisionamento de tenants
patch-041ClientesPolítica anon SELECT em ai_usage_log (monitoramento do admin)
supabase/modules/cardiologia.sqlClientes cardiologia10 tabelas do módulo cardiológico
📡
Monitoramento (APM)
Saúde dos sites, erros JS, status da IA — tudo visível no dashboard
Health Check horário
health-check.yml
Roda automaticamente todo hora. Pinga os 3 sites (Eriane, Carlos, Core). Salva o resultado em client_health_snapshots no vertice-admin. Se offline → e-mail automático via GitHub.
Automático
Erros JS em produção
error-logger.js
Captura window.onerror e unhandledrejection em todas as 39 páginas da Eriane. Salva silenciosamente em error_log no Supabase do cliente. Visível no dashboard → Monitoramento.
Automático
Status da IA Gemini
ai_usage_log 🟢🟡🔴
Cada chamada ao gemini-proxy registra: tokens, latência, cache hit, erro. O dashboard admin mostra 🟢 (OK) / 🟡 (sem chamadas) / 🔴 (chave inválida ou quota) por cliente.
Automático
Ver tudo
Dashboard → Monitoramento
No dashboard.html, seção Monitoramento: status de cada servidor, uptime %, status da chave Gemini por cliente e últimas chamadas de IA.
Manual — verificar
🧠
IA — Gemini Proxy
Como a IA funciona, onde fica a chave, como monitorar
Browser (página)
→
gemini-proxy
Edge Function Supabase
→
ai_cache
24h TTL
→
Gemini API
google.com
🔑
Chave Gemini — onde fica
A chave fica somente nos secrets do Supabase do cliente (nunca no código). Para ver/editar: Supabase Dashboard → Edge Functions → gemini-proxy → Secrets → GEMINI_API_KEY. Começa com AQ.Ab (formato novo Google), nunca AIzaSy.
🔄
Cache de 24h
Respostas com mais de 500 tokens são cacheadas na tabela ai_cache por 24h. Se a mesma pergunta chegar novamente, o proxy responde do cache sem chamar a Gemini API. Economiza quota e reduz latência.
🚨
Chave inválida ou quota esgotada
O dashboard mostra 🔴 no cliente. Verificar em ai_usage_log o campo error — se contiver HTTP 429 = quota esgotada; HTTP 401 = chave inválida. Corrigir o secret no Supabase e re-deployar a Edge Function se necessário:
supabase functions deploy gemini-proxy --project-ref REF --no-verify-jwt
🔄
Propagação de Código
Como as atualizações chegam de template-master para todos os clientes
📋
Regra Template Master First: Nenhuma feature vai direto em cliente. Sempre: template-master/ → teste → aprovação → rodar update-all.js → deploy.
1
Sincronizar core/ → template-master + clientes
# Propaga core/supabase/, core/auth/, core/ui/ para todos os clientes node scripts/sync-core.js
2
Propagar template-master → clientes
# Todos os clientes node scripts/update-all.js --todos # Cliente específico node scripts/update-all.js --cliente eriane-faria # Simular sem alterar node scripts/update-all.js --todos --dry-run
O update-all.js também propaga automaticamente apps/tenant/sw.js → clientes/[slug]/sw.js (raiz). Nunca sobrescreve: config.json, branding/, arquivos mais novos no cliente.
3
Verificar cliente antes de commitar
.\scripts\verificar-cliente.ps1 -cliente eriane-faria
Verifica: logo.svg · favicon.svg · config.json preenchido · config-loader.js · tema.css. Não commitar se falhar.
🧪
Testes Automáticos
Playwright — 25+ testes cobrindo fluxos críticos de negócio
▶
Rodar todos os testes
# Subir servidor do carlos-mendes na 3001 antes node scripts/_serve-carlos.js # em outro terminal # Rodar os testes npm test # playwright test npm run test:auth # só T-01, T-04, T-17 npm run test:redirects # 10 rotas protegidas npm run test:medico # médico navega páginas npm run test:unit # testes unitários (sem browser)
ArquivoTestesO que cobre
auth.spec.tsT-01, T-04, T-17Login médico, sessão expirada, prontuário sem auth
redirects.spec.tsT-06 (10 rotas)Páginas protegidas → redirect login sem sessão
roles.spec.tsT-03, T-18Paciente e secretaria não acessam prontuário
medico.spec.tsT-11 a T-16Médico navega agenda, mensagens, financeiro, IA, monitoramento
secretaria.spec.tsT-02, T-05Secretaria login e cadastro de paciente
modulos.spec.tsT-07Módulo desativado → comportamento correto
unit/provisioning.spec.tsT-02 (8 testes)Scripts de provisionamento: args, SQL, integridade
unit/update-all.spec.tsT-08, T-09update-all.js preserva config.json e customizações
🔧
Troubleshooting
Problemas comuns e como resolver
Admin retorna 401 do Supabase em todas as páginas ▼
Causa: CDN do supabase-js não carregado → window.supabase undefined → todas as chamadas falham.

Fix: Verificar que apps/admin/dashboard.html tem a tag <script src="cdn.jsdelivr.net/...supabase.min.js">. Fazer deploy manual se necessário.
Deploy do admin não chegou ao servidor após push ▼
Causa: GitHub Actions com delay, falha silenciosa ou chave SSH não autorizada no servidor Vértice.

Fix: Verificar data do arquivo no servidor via SSH: ssh -p 65002 -i ~/.ssh/hostinger_key u627878224@82.180.153.142 "stat /home/u627878224/.../core/dashboard.html". Se a data for anterior ao commit, fazer deploy manual via SCP.
Multiple GoTrueClient warnings no console ▼
Causa: Múltiplos clientes Supabase criados no mesmo contexto de browser sem storageKey único.

Fix: Ao criar clientes para health checks, usar: { auth: { persistSession: false, autoRefreshToken: false, storageKey: 'vertice_health_REF' } }.
401 em ai_usage_log no admin dashboard ▼
Causa: A tabela ai_usage_log foi criada sem política anon SELECT (patch-035 só tem service_role).

Fix: Aplicar patch-041: node scripts/provisioning/schema.js --ref REF --pat PAT --file supabase/patch-041-ai-usage-log-anon-select.sql
Site da Eriane com tela em branco após update-all.js ▼
Causa provável: Arquivo core com import ESModule foi propagado para clientes/eriane-faria/assets/js/. Scripts com import causam SyntaxError quando carregados como <script src> (não module).

Fix: Verificar clientes/eriane-faria/assets/js/supabase.js com grep "^import" clientes/eriane-faria/assets/js/supabase.js. Se tiver import, restaurar da versão anterior no git: git checkout HEAD~1 -- clientes/eriane-faria/assets/js/supabase.js. Os arquivos em core/ NÃO devem ter import/export de ES6 até o build Vite estar configurado em produção.
Ping do monitoramento retorna 403 no Core Vértice ▼
Causa: A URL de ping estava apontando para a raiz / que retorna 403 (Hostinger bloqueia listagem de diretório).

Fix: URL de ping deve ser https://core.vertice-ecossistema.com.br/login.html (um arquivo específico, não a raiz). Já corrigido em dashboard.html.
Supabase Management API retorna 429 (rate limit) ▼
Causa: Muitas chamadas em sequência rápida (ex: aplicar schema com muitos statements).

Fix: O schema.js já usa 130ms de delay entre statements. Para operações manuais em lote, aguardar 120–150ms entre chamadas à API.
Criar usuário no Supabase retorna "Database error querying schema" ▼
Causa: Tentativa de criar usuário via SQL direto no Supabase ao invés da GoTrue Admin API.

Fix: Usar sempre a GoTrue Admin API (service_role key): POST https://[ref].supabase.co/auth/v1/admin/users com body {"email":"...", "password":"...", "email_confirm":true}. NUNCA inserir direto em auth.users via SQL.
🔐
Credenciais e Referências Rápidas
Onde encontrar o quê (nunca commitar senhas/chaves)
🚨
Segurança: Nenhuma senha ou chave API aparece nesta página. Todas as credenciais ficam localmente em config.json (gitignored) ou nos secrets do Supabase/GitHub.
O queOnde encontrar
Supabase URLs e anon_keysArquivo local clientes/[slug]/config.json (nunca commitado). Ou Supabase Dashboard → Settings → API
Supabase PATs (Management API)supabase.com/dashboard/account/tokens — cada conta tem o seu
Chave Gemini APISecrets da Edge Function gemini-proxy no Supabase do cliente. Nunca no código.
SSH Eriane (82.25.67.107)Chave: ~/.ssh/hostinger_key · Usuário: u707423342 · Porta: 65002
SSH Vértice Core (82.180.153.142)Mesma chave hostinger_key · Usuário: u627878224 · Porta: 65002
Config admin (vertice.config.json)Arquivo local apps/admin/vertice.config.json (gitignored)
Login admin Léolcunhapereira@gmail.com / senha no Supabase vertice-admin
GitHub Actions secretsgithub.com/vertice-health/vertice-health-platform/settings/secrets/actions
Sistema Mestre — Vértice Health Platform · Atualizado em